diff options
Diffstat (limited to 'source/blender/editors')
141 files changed, 3279 insertions, 3111 deletions
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 3608140a29d..e7c7f679b16 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -402,6 +402,7 @@ static void draw_marker_name(const uchar *text_color, const uiFontStyle *fstyle, TimeMarker *marker, float marker_x, + float xmax, float text_y) { const char *name = marker->name; @@ -419,8 +420,16 @@ static void draw_marker_name(const uchar *text_color, } #endif - int name_x = marker_x + UI_DPI_ICON_SIZE * 0.6; - UI_fontstyle_draw_simple(fstyle, name_x, text_y, name, final_text_color); + const int icon_half_width = UI_DPI_ICON_SIZE * 0.6; + const struct uiFontStyleDraw_Params fs_params = {.align = UI_STYLE_TEXT_LEFT, .word_wrap = 0}; + const struct rcti rect = { + .xmin = marker_x + icon_half_width, + .xmax = xmax - icon_half_width, + .ymin = text_y, + .ymax = text_y, + }; + + UI_fontstyle_draw(fstyle, &rect, name, strlen(name), final_text_color, &fs_params); } static void draw_marker_line(const uchar *color, int xpos, int ymin, int ymax) @@ -462,8 +471,13 @@ static int marker_get_icon_id(TimeMarker *marker, int flag) return (marker->flag & SELECT) ? ICON_MARKER_HLT : ICON_MARKER; } -static void draw_marker( - const uiFontStyle *fstyle, TimeMarker *marker, int cfra, int xpos, int flag, int region_height) +static void draw_marker(const uiFontStyle *fstyle, + TimeMarker *marker, + int xpos, + int xmax, + int flag, + int region_height, + bool is_elevated) { uchar line_color[4], text_color[4]; @@ -479,12 +493,11 @@ static void draw_marker( GPU_blend(GPU_BLEND_NONE); float name_y = UI_DPI_FAC * 18; - /* Give an offset to the marker name when selected, - * or when near the current frame (5 frames range, starting from the current one). */ - if ((marker->flag & SELECT) || (cfra - 4 <= marker->frame && marker->frame <= cfra)) { + /* Give an offset to the marker that is elevated. */ + if (is_elevated) { name_y += UI_DPI_FAC * 10; } - draw_marker_name(text_color, fstyle, marker, xpos, name_y); + draw_marker_name(text_color, fstyle, marker, xpos, xmax, name_y); } static void draw_markers_background(rctf *rect) @@ -532,6 +545,14 @@ static void get_marker_clip_frame_range(View2D *v2d, float xscale, int r_range[2 r_range[1] = v2d->cur.xmax + font_width_max; } +static int markers_frame_sort(const void *a, const void *b) +{ + const TimeMarker *marker_a = a; + const TimeMarker *marker_b = b; + + return marker_a->frame > marker_b->frame; +} + void ED_markers_draw(const bContext *C, int flag) { ListBase *markers = ED_context_get_markers(C); @@ -561,22 +582,69 @@ void ED_markers_draw(const bContext *C, int flag) const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; - /* Separate loops in order to draw selected markers on top */ - LISTBASE_FOREACH (TimeMarker *, marker, markers) { - if ((marker->flag & SELECT) == 0) { - if (marker_is_in_frame_range(marker, clip_frame_range)) { - draw_marker(fstyle, marker, cfra, marker->frame * xscale, flag, region->winy); - } + /* Markers are not stored by frame order, so we need to sort it here. */ + ListBase sorted_markers; + + BLI_duplicatelist(&sorted_markers, markers); + BLI_listbase_sort(&sorted_markers, markers_frame_sort); + + /** + * Set a temporary bit in the marker's flag to indicate that it should be elevated. + * This bit will be flipped back at the end of this function. + */ + const int ELEVATED = 0x10; + LISTBASE_FOREACH (TimeMarker *, marker, &sorted_markers) { + const bool is_elevated = (marker->flag & SELECT) || + (cfra >= marker->frame && + (marker->next == NULL || cfra < marker->next->frame)); + SET_FLAG_FROM_TEST(marker->flag, is_elevated, ELEVATED); + } + + /* Separate loops in order to draw selected markers on top. */ + + /** + * Draw non-elevated markers first. + * Note that unlike the elevated markers, these marker names will always be clipped by the + * proceeding marker. This is done because otherwise, the text overlaps with the icon of the + * marker itself. + */ + LISTBASE_FOREACH (TimeMarker *, marker, &sorted_markers) { + if ((marker->flag & ELEVATED) == 0 && marker_is_in_frame_range(marker, clip_frame_range)) { + const int xmax = marker->next ? marker->next->frame : clip_frame_range[1] + 1; + draw_marker( + fstyle, marker, marker->frame * xscale, xmax * xscale, flag, region->winy, false); } } - LISTBASE_FOREACH (TimeMarker *, marker, markers) { - if (marker->flag & SELECT) { - if (marker_is_in_frame_range(marker, clip_frame_range)) { - draw_marker(fstyle, marker, cfra, marker->frame * xscale, flag, region->winy); - } + + /* Now draw the elevated markers */ + for (TimeMarker *marker = sorted_markers.first; marker != NULL;) { + + /* Skip this marker if it is elevated or out of the frame range. */ + if ((marker->flag & ELEVATED) == 0 || !marker_is_in_frame_range(marker, clip_frame_range)) { + marker = marker->next; + continue; } + + /* Find the next elevated marker. */ + /* We use the next marker to determine how wide our text should be */ + TimeMarker *next_marker = marker->next; + while (next_marker != NULL && (next_marker->flag & ELEVATED) == 0) { + next_marker = next_marker->next; + } + + const int xmax = next_marker ? next_marker->frame : clip_frame_range[1] + 1; + draw_marker(fstyle, marker, marker->frame * xscale, xmax * xscale, flag, region->winy, true); + + marker = next_marker; } + /* Reset the elevated flag. */ + LISTBASE_FOREACH (TimeMarker *, marker, &sorted_markers) { + marker->flag &= ~ELEVATED; + } + + BLI_freelistN(&sorted_markers); + GPU_matrix_pop(); } diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index 08d5d6558e0..ae15bc39ec8 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -59,7 +59,7 @@ Base *ED_armature_base_and_ebone_from_select_buffer(Base **bases, const uint hit_object = select_id & 0xFFFF; Base *base = NULL; EditBone *ebone = NULL; - /* TODO(campbell): optimize, eg: sort & binary search. */ + /* TODO(@campbellbarton): optimize, eg: sort & binary search. */ for (uint base_index = 0; base_index < bases_len; base_index++) { if (bases[base_index]->object->runtime.select_id == hit_object) { base = bases[base_index]; @@ -83,7 +83,7 @@ Object *ED_armature_object_and_ebone_from_select_buffer(Object **objects, const uint hit_object = select_id & 0xFFFF; Object *ob = NULL; EditBone *ebone = NULL; - /* TODO(campbell): optimize, eg: sort & binary search. */ + /* TODO(@campbellbarton): optimize, eg: sort & binary search. */ for (uint ob_index = 0; ob_index < objects_len; ob_index++) { if (objects[ob_index]->runtime.select_id == hit_object) { ob = objects[ob_index]; @@ -107,7 +107,7 @@ Base *ED_armature_base_and_pchan_from_select_buffer(Base **bases, const uint hit_object = select_id & 0xFFFF; Base *base = NULL; bPoseChannel *pchan = NULL; - /* TODO(campbell): optimize, eg: sort & binary search. */ + /* TODO(@campbellbarton): optimize, eg: sort & binary search. */ for (uint base_index = 0; base_index < bases_len; base_index++) { if (bases[base_index]->object->runtime.select_id == hit_object) { base = bases[base_index]; @@ -1452,7 +1452,7 @@ static void armature_select_more_less(Object *ob, bool more) bArmature *arm = (bArmature *)ob->data; EditBone *ebone; - /* XXX(campbell): eventually we shouldn't need this. */ + /* XXX(@campbellbarton): eventually we shouldn't need this. */ ED_armature_edit_sync_selection(arm->edbo); /* count bones & store selection state */ diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index b6b5d3ee495..6756dec1c95 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -166,7 +166,7 @@ bool ED_armature_pose_select_pick_bone(ViewLayer *view_layer, /* Since we do unified select, we don't shift+select a bone if the * armature object was not active yet. - * NOTE(campbell): special exception for armature mode so we can do multi-select + * NOTE(@campbellbarton): special exception for armature mode so we can do multi-select * we could check for multi-select explicitly but think its fine to * always give predictable behavior in weight paint mode. */ if ((ob_act == NULL) || ((ob_act != ob) && (ob_act->mode & OB_MODE_ALL_WEIGHT_PAINT) == 0)) { diff --git a/source/blender/editors/asset/ED_asset_list.h b/source/blender/editors/asset/ED_asset_list.h index 2dc67fc4d37..b54f81004f2 100644 --- a/source/blender/editors/asset/ED_asset_list.h +++ b/source/blender/editors/asset/ED_asset_list.h @@ -24,7 +24,7 @@ struct wmNotifier; void ED_assetlist_storage_fetch(const struct AssetLibraryReference *library_reference, const struct bContext *C); void ED_assetlist_ensure_previews_job(const struct AssetLibraryReference *library_reference, - struct bContext *C); + const struct bContext *C); void ED_assetlist_clear(const struct AssetLibraryReference *library_reference, struct bContext *C); bool ED_assetlist_storage_has_list_for_library(const AssetLibraryReference *library_reference); /** diff --git a/source/blender/editors/asset/intern/asset_library_reference_enum.cc b/source/blender/editors/asset/intern/asset_library_reference_enum.cc index 67e253a4fcd..773838a54cd 100644 --- a/source/blender/editors/asset/intern/asset_library_reference_enum.cc +++ b/source/blender/editors/asset/intern/asset_library_reference_enum.cc @@ -97,10 +97,8 @@ const EnumPropertyItem *ED_asset_library_reference_to_rna_enum_itemf( RNA_enum_item_add_separator(&item, &totitem); } - int i = 0; - for (bUserAssetLibrary *user_library = (bUserAssetLibrary *)U.asset_libraries.first; - user_library; - user_library = user_library->next, i++) { + int i; + LISTBASE_FOREACH_INDEX (bUserAssetLibrary *, user_library, &U.asset_libraries, i) { /* Note that the path itself isn't checked for validity here. If an invalid library path is * used, the Asset Browser can give a nice hint on what's wrong. */ const bool is_valid = (user_library->name[0] && user_library->path[0]); diff --git a/source/blender/editors/asset/intern/asset_list.cc b/source/blender/editors/asset/intern/asset_list.cc index 55167c1ed2d..b0ff5c86520 100644 --- a/source/blender/editors/asset/intern/asset_list.cc +++ b/source/blender/editors/asset/intern/asset_list.cc @@ -110,7 +110,7 @@ class AssetList : NonCopyable { void setup(); void fetch(const bContext &C); - void ensurePreviewsJob(bContext *C); + void ensurePreviewsJob(const bContext *C); void clear(bContext *C); bool needsRefetch() const; @@ -212,7 +212,7 @@ void AssetList::iterate(AssetListIterFn fn) const } } -void AssetList::ensurePreviewsJob(bContext *C) +void AssetList::ensurePreviewsJob(const bContext *C) { FileList *files = filelist_; int numfiles = filelist_files_ensure(files); @@ -422,7 +422,8 @@ void ED_assetlist_storage_fetch(const AssetLibraryReference *library_reference, AssetListStorage::fetch_library(*library_reference, *C); } -void ED_assetlist_ensure_previews_job(const AssetLibraryReference *library_reference, bContext *C) +void ED_assetlist_ensure_previews_job(const AssetLibraryReference *library_reference, + const bContext *C) { AssetList *list = AssetListStorage::lookup_list(*library_reference); diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index 24302aca59b..164336c4b22 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -1279,7 +1279,7 @@ void ED_curve_editnurb_make(Object *obedit) if (actkey) { // XXX strcpy(G.editModeTitleExtra, "(Key) "); - /* TODO(campbell): undo_system: investigate why this was needed. */ + /* TODO(@campbellbarton): undo_system: investigate why this was needed. */ #if 0 undo_editmode_clear(); #endif @@ -1541,67 +1541,6 @@ void CURVE_OT_split(wmOperatorType *ot) /** \name Flag Utility Functions * \{ */ -static bool isNurbselUV(const Nurb *nu, uint8_t flag, int *r_u, int *r_v) -{ - /* return (u != -1): 1 row in u-direction selected. U has value between 0-pntsv - * return (v != -1): 1 column in v-direction selected. V has value between 0-pntsu - */ - BPoint *bp; - int a, b, sel; - - *r_u = *r_v = -1; - - bp = nu->bp; - for (b = 0; b < nu->pntsv; b++) { - sel = 0; - for (a = 0; a < nu->pntsu; a++, bp++) { - if (bp->f1 & flag) { - sel++; - } - } - if (sel == nu->pntsu) { - if (*r_u == -1) { - *r_u = b; - } - else { - return 0; - } - } - else if (sel > 1) { - return 0; /* because sel == 1 is still ok */ - } - } - - for (a = 0; a < nu->pntsu; a++) { - sel = 0; - bp = &nu->bp[a]; - for (b = 0; b < nu->pntsv; b++, bp += nu->pntsu) { - if (bp->f1 & flag) { - sel++; - } - } - if (sel == nu->pntsv) { - if (*r_v == -1) { - *r_v = a; - } - else { - return 0; - } - } - else if (sel > 1) { - return 0; - } - } - - if (*r_u == -1 && *r_v > -1) { - return 1; - } - if (*r_v == -1 && *r_u > -1) { - return 1; - } - return 0; -} - /* return true if U direction is selected and number of selected columns v */ static bool isNurbselU(Nurb *nu, int *v, int flag) { @@ -1976,119 +1915,201 @@ static void ed_curve_delete_selected(Object *obedit, View3D *v3d) } } -bool ed_editnurb_extrude_flag(EditNurb *editnurb, const uint8_t flag) +static void select_bpoints(BPoint *bp, + const int stride, + const int count, + const bool selstatus, + const uint8_t flag, + const bool hidden) { - BPoint *bp, *bpn, *newbp; - int a, u, v, len; - bool ok = false; + for (int i = 0; i < count; i++) { + select_bpoint(bp, selstatus, flag, hidden); + bp += stride; + } +} - LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { - if (nu->pntsv == 1) { - bp = nu->bp; - a = nu->pntsu; - while (a) { - if (bp->f1 & flag) { - /* pass */ - } - else { - break; - } - bp++; - a--; - } - if (a == 0) { - ok = true; - newbp = (BPoint *)MEM_mallocN(2 * nu->pntsu * sizeof(BPoint), "extrudeNurb1"); - ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu); - bp = newbp + nu->pntsu; - ED_curve_bpcpy(editnurb, bp, nu->bp, nu->pntsu); - MEM_freeN(nu->bp); - nu->bp = newbp; - a = nu->pntsu; - while (a--) { - select_bpoint(bp, SELECT, flag, HIDDEN); - select_bpoint(newbp, DESELECT, flag, HIDDEN); - bp++; - newbp++; - } +/** + * Calculate and return fully selected legs along i dimension. + * Calculates intervals to create extrusion by duplicating existing points while copied to + * destination NURBS. For ex. for curve of 3 points indexed by 0..2 to extrude first and last + * point copy intervals would be [0, 0][0, 2][2, 2]. Representation in copy_intervals array would + * be [0, 0, 2, 2]. Returns -1 if selection is not valid. + */ +static int sel_to_copy_ints(const BPoint *bp, + const int next_j, + const int max_j, + const int next_i, + const int max_i, + const uint8_t flag, + int copy_intervals[], + int *interval_count, + bool *out_is_first_sel) +{ + const BPoint *bp_j = bp; - nu->pntsv = 2; - nu->orderv = 2; - BKE_nurb_knot_calc_v(nu); - } - } - else { - /* which row or column is selected */ + int selected_leg_count = 0; + int ins = 0; + int selected_in_prev_leg = -1; + int not_full = -1; - if (isNurbselUV(nu, flag, &u, &v)) { + bool is_first_sel = false; + bool is_last_sel = false; - /* deselect all */ - bp = nu->bp; - a = nu->pntsu * nu->pntsv; - while (a--) { - select_bpoint(bp, DESELECT, flag, HIDDEN); - bp++; - } + for (int j = 0; j < max_j; j++, bp_j += next_j) { + const BPoint *bp_j_i = bp_j; + int selected_in_curr_leg = 0; + for (int i = 0; i < max_i; i++, bp_j_i += next_i) { + if (bp_j_i->f1 & flag) { + selected_in_curr_leg++; + } + } + if (selected_in_curr_leg == max_i) { + selected_leg_count++; + if (j == 0) { + is_first_sel = true; + } + else if (j + 1 == max_j) { + is_last_sel = true; + } + } + else if (not_full == -1) { + not_full = selected_in_curr_leg; + } + /* We have partially selected leg in opposite dimension if condition is met. */ + else if (not_full != selected_in_curr_leg) { + return -1; + } + /* Extrusion area starts/ends if met. */ + if (selected_in_prev_leg != selected_in_curr_leg) { + copy_intervals[ins] = selected_in_curr_leg == max_i || j == 0 ? j : j - 1; + ins++; + selected_in_prev_leg = selected_in_curr_leg; + } + copy_intervals[ins] = j; + } + if (selected_leg_count && + /* Prevents leading and trailing unselected legs if all selected. + * Unless it is extrusion from point or curve.*/ + (selected_leg_count < max_j || max_j == 1)) { + /* Prepend unselected leg if more than one leg selected at the starting edge. + * max_j == 1 handles extrusion from point to curve and from curve to surface cases. */ + if (is_first_sel && (copy_intervals[0] < copy_intervals[1] || max_j == 1)) { + memmove(copy_intervals + 1, copy_intervals, (ins + 1) * sizeof(copy_intervals[0])); + copy_intervals[0] = 0; + ins++; + is_first_sel = false; + } + /* Append unselected leg if more than one leg selected at the end. */ + if (is_last_sel && copy_intervals[ins - 1] < copy_intervals[ins]) { + copy_intervals[ins + 1] = copy_intervals[ins]; + ins++; + } + } + *interval_count = ins; + *out_is_first_sel = ins > 1 ? is_first_sel : false; + return selected_leg_count; +} - if (ELEM(u, 0, nu->pntsv - 1)) { /* row in u-direction selected */ - ok = true; - newbp = (BPoint *)MEM_mallocN(nu->pntsu * (nu->pntsv + 1) * sizeof(BPoint), - "extrudeNurb1"); - if (u == 0) { - len = nu->pntsv * nu->pntsu; - ED_curve_bpcpy(editnurb, newbp + nu->pntsu, nu->bp, len); - ED_curve_bpcpy(editnurb, newbp, nu->bp, nu->pntsu); - bp = newbp; - } - else { - len = nu->pntsv * nu->pntsu; - ED_curve_bpcpy(editnurb, newbp, nu->bp, len); - ED_curve_bpcpy(editnurb, newbp + len, &nu->bp[len - nu->pntsu], nu->pntsu); - bp = newbp + len; - } +typedef struct NurbDim { + int pntsu; + int pntsv; +} NurbDim; - a = nu->pntsu; - while (a--) { - select_bpoint(bp, SELECT, flag, HIDDEN); - bp++; - } +static NurbDim editnurb_find_max_points_num(const EditNurb *editnurb) +{ + NurbDim ret = {0, 0}; + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { + if (nu->pntsu > ret.pntsu) { + ret.pntsu = nu->pntsu; + } + if (nu->pntsv > ret.pntsv) { + ret.pntsv = nu->pntsv; + } + } + return ret; +} - MEM_freeN(nu->bp); - nu->bp = newbp; - nu->pntsv++; - BKE_nurb_knot_calc_v(nu); - } - else if (ELEM(v, 0, nu->pntsu - 1)) { /* column in v-direction selected */ - ok = true; - bpn = newbp = (BPoint *)MEM_mallocN((nu->pntsu + 1) * nu->pntsv * sizeof(BPoint), - "extrudeNurb1"); - bp = nu->bp; +bool ed_editnurb_extrude_flag(EditNurb *editnurb, const uint8_t flag) +{ + const NurbDim max = editnurb_find_max_points_num(editnurb); + /* One point induces at most one interval. Except single point case, it can give + 1. + * Another +1 is for first element of the first interval. */ + int *const intvls_u = MEM_malloc_arrayN(max.pntsu + 2, sizeof(int), "extrudeNurb0"); + int *const intvls_v = MEM_malloc_arrayN(max.pntsv + 2, sizeof(int), "extrudeNurb1"); + bool ok = false; - for (a = 0; a < nu->pntsv; a++) { - if (v == 0) { - *bpn = *bp; - bpn->f1 |= flag; - bpn++; - } - ED_curve_bpcpy(editnurb, bpn, bp, nu->pntsu); - bp += nu->pntsu; - bpn += nu->pntsu; - if (v == nu->pntsu - 1) { - *bpn = *(bp - 1); - bpn->f1 |= flag; - bpn++; - } - } + LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { + int intvl_cnt_u; + bool is_first_sel_u; - MEM_freeN(nu->bp); - nu->bp = newbp; - nu->pntsu++; - BKE_nurb_knot_calc_u(nu); - } - } + /* Calculate selected U legs and intervals for their extrusion. */ + const int selected_us = sel_to_copy_ints( + nu->bp, 1, nu->pntsu, nu->pntsu, nu->pntsv, flag, intvls_u, &intvl_cnt_u, &is_first_sel_u); + if (selected_us == -1) { + continue; } - } + int intvl_cnt_v; + bool is_first_sel_v; + const bool is_point = nu->pntsu == 1; + const bool is_curve = nu->pntsv == 1; + const bool extrude_every_u_point = selected_us == nu->pntsu; + if (is_point || (is_curve && !extrude_every_u_point)) { + intvls_v[0] = intvls_v[1] = 0; + intvl_cnt_v = 1; + is_first_sel_v = false; + } + else { + sel_to_copy_ints(nu->bp, + nu->pntsu, + nu->pntsv, + 1, + nu->pntsu, + flag, + intvls_v, + &intvl_cnt_v, + &is_first_sel_v); + } + + const int new_pntsu = nu->pntsu + intvl_cnt_u - 1; + const int new_pntsv = nu->pntsv + intvl_cnt_v - 1; + BPoint *const new_bp = (BPoint *)MEM_malloc_arrayN( + new_pntsu * new_pntsv, sizeof(BPoint), "extrudeNurb2"); + BPoint *new_bp_v = new_bp; + + bool selected_v = is_first_sel_v; + for (int j = 1; j <= intvl_cnt_v; j++, selected_v = !selected_v) { + BPoint *old_bp_v = nu->bp + intvls_v[j - 1] * nu->pntsu; + for (int v_j = intvls_v[j - 1]; v_j <= intvls_v[j]; + v_j++, new_bp_v += new_pntsu, old_bp_v += nu->pntsu) { + BPoint *new_bp_u_v = new_bp_v; + bool selected_u = is_first_sel_u; + for (int i = 1; i <= intvl_cnt_u; i++, selected_u = !selected_u) { + const int copy_from = intvls_u[i - 1]; + const int copy_to = intvls_u[i]; + const int copy_count = copy_to - copy_from + 1; + const bool sel_status = selected_u || selected_v ? SELECT : DESELECT; + ED_curve_bpcpy(editnurb, new_bp_u_v, old_bp_v + copy_from, copy_count); + select_bpoints(new_bp_u_v, 1, copy_count, sel_status, flag, HIDDEN); + new_bp_u_v += copy_count; + } + } + } + + MEM_freeN(nu->bp); + nu->bp = new_bp; + nu->pntsu = new_pntsu; + if (nu->pntsv == 1 && new_pntsv > 1) { + nu->orderv = 2; + } + nu->pntsv = new_pntsv; + BKE_nurb_knot_calc_u(nu); + BKE_nurb_knot_calc_v(nu); + + ok = true; + } + MEM_freeN(intvls_u); + MEM_freeN(intvls_v); return ok; } @@ -5695,23 +5716,12 @@ static int curve_extrude_exec(bContext *C, wmOperator *UNUSED(op)) Curve *cu = obedit->data; EditNurb *editnurb = cu->editnurb; bool changed = false; - bool as_curve = false; if (!ED_curve_select_check(v3d, cu->editnurb)) { continue; } - /* First test: curve? */ - if (obedit->type != OB_CURVES_LEGACY) { - LISTBASE_FOREACH (Nurb *, nu, &editnurb->nurbs) { - if ((nu->pntsv == 1) && (ED_curve_nurb_select_count(v3d, nu) < nu->pntsu)) { - as_curve = true; - break; - } - } - } - - if (obedit->type == OB_CURVES_LEGACY || as_curve) { + if (obedit->type == OB_CURVES_LEGACY) { changed = ed_editcurve_extrude(cu, editnurb, v3d); } else { diff --git a/source/blender/editors/curves/CMakeLists.txt b/source/blender/editors/curves/CMakeLists.txt index 303d2fb71dc..945bba0a77c 100644 --- a/source/blender/editors/curves/CMakeLists.txt +++ b/source/blender/editors/curves/CMakeLists.txt @@ -13,6 +13,7 @@ set(INC ../../makesrna ../../windowmanager ../../../../intern/guardedalloc + ../../bmesh # RNA_prototypes.h ${CMAKE_BINARY_DIR}/source/blender/makesrna diff --git a/source/blender/editors/geometry/CMakeLists.txt b/source/blender/editors/geometry/CMakeLists.txt index e0c440b09b4..6e28bb3e8ec 100644 --- a/source/blender/editors/geometry/CMakeLists.txt +++ b/source/blender/editors/geometry/CMakeLists.txt @@ -10,6 +10,7 @@ set(INC ../../makesrna ../../windowmanager ../../../../intern/guardedalloc + ../../bmesh ) set(INC_SYS diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt index 09a3cac0d48..9cb9e7ca1af 100644 --- a/source/blender/editors/gpencil/CMakeLists.txt +++ b/source/blender/editors/gpencil/CMakeLists.txt @@ -14,6 +14,7 @@ set(INC ../../windowmanager ../../../../intern/glew-mx ../../../../intern/guardedalloc + ../../bmesh # RNA_prototypes.h ${CMAKE_BINARY_DIR}/source/blender/makesrna ) diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index b73b62d5a9d..9d3fd5af47f 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -144,6 +144,7 @@ void BM_uv_element_map_free(struct UvElementMap *element_map); struct UvElement *BM_uv_element_get(struct UvElementMap *map, struct BMFace *efa, struct BMLoop *l); +struct UvElement *BM_uv_element_get_head(struct UvElementMap *map, struct UvElement *child); /** * Can we edit UV's for this mesh? @@ -552,16 +553,10 @@ void ED_mesh_uv_loop_reset_ex(struct Mesh *me, int layernum); bool ED_mesh_color_ensure(struct Mesh *me, const char *name); int ED_mesh_color_add( struct Mesh *me, const char *name, bool active_set, bool do_init, struct ReportList *reports); -bool ED_mesh_color_remove_index(struct Mesh *me, int n); -bool ED_mesh_color_remove_active(struct Mesh *me); -bool ED_mesh_color_remove_named(struct Mesh *me, const char *name); - -bool ED_mesh_sculpt_color_ensure(struct Mesh *me, const char *name); -int ED_mesh_sculpt_color_add( - struct Mesh *me, const char *name, bool active_set, bool do_init, struct ReportList *reports); -bool ED_mesh_sculpt_color_remove_index(struct Mesh *me, int n); -bool ED_mesh_sculpt_color_remove_active(struct Mesh *me); -bool ED_mesh_sculpt_color_remove_named(struct Mesh *me, const char *name); +int ED_mesh_sculpt_color_add(struct Mesh *me, + const char *name, + bool do_init, + struct ReportList *reports); void ED_mesh_report_mirror(struct wmOperator *op, int totmirr, int totfail); void ED_mesh_report_mirror_ex(struct wmOperator *op, int totmirr, int totfail, char selectmode); diff --git a/source/blender/editors/include/ED_uvedit.h b/source/blender/editors/include/ED_uvedit.h index 80a75da27f8..24d6819536d 100644 --- a/source/blender/editors/include/ED_uvedit.h +++ b/source/blender/editors/include/ED_uvedit.h @@ -305,6 +305,29 @@ void ED_uvedit_buttons_register(struct ARegionType *art); /* uvedit_islands.c */ +struct FaceIsland { + struct FaceIsland *next; + struct FaceIsland *prev; + struct BMFace **faces; + int faces_len; + rctf bounds_rect; + /** + * \note While this is duplicate information, + * it allows islands from multiple meshes to be stored in the same list. + */ + uint cd_loop_uv_offset; + float aspect_y; +}; + +int bm_mesh_calc_uv_islands(const Scene *scene, + struct BMesh *bm, + ListBase *island_list, + const bool only_selected_faces, + const bool only_selected_uvs, + const bool use_seams, + const float aspect_y, + const uint cd_loop_uv_offset); + struct UVMapUDIM_Params { const struct Image *image; /** Copied from #SpaceImage.tile_grid_shape */ diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 7d31950c869..bb95ea97c1c 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -1171,7 +1171,7 @@ void ED_view3d_camera_lock_init(const struct Depsgraph *depsgraph, * * Apply the 3D Viewport transformation back to the camera object. * - * \return true if the camera is moved. + * \return true if the camera (or one of it's parents) was moved. */ bool ED_view3d_camera_lock_sync(const struct Depsgraph *depsgraph, struct View3D *v3d, @@ -1211,8 +1211,8 @@ bool ED_view3d_camera_lock_undo_test(const View3D *v3d, * \return true when the call to push an undo step was made. */ bool ED_view3d_camera_lock_undo_push(const char *str, - View3D *v3d, - struct RegionView3D *rv3d, + const View3D *v3d, + const struct RegionView3D *rv3d, struct bContext *C); /** @@ -1222,8 +1222,8 @@ bool ED_view3d_camera_lock_undo_push(const char *str, * where adding a separate undo step each time isn't desirable. */ bool ED_view3d_camera_lock_undo_grouped_push(const char *str, - View3D *v3d, - struct RegionView3D *rv3d, + const View3D *v3d, + const struct RegionView3D *rv3d, struct bContext *C); #define VIEW3D_MARGIN 1.4f diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index a8d25b75036..163ea7e9493 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -85,7 +85,7 @@ typedef struct uiViewItemHandle uiViewItemHandle; /* Separator for text in search menus (right pointing arrow). * keep in sync with `string_search.cc`. */ -#define UI_MENU_ARROW_SEP "\xe2\x96\xb6" +#define UI_MENU_ARROW_SEP "\xe2\x96\xb8" /* names */ #define UI_MAX_DRAW_STR 400 @@ -2482,7 +2482,7 @@ enum uiTemplateListFlags { ENUM_OPERATORS(enum uiTemplateListFlags, UI_TEMPLATE_LIST_FLAGS_LAST); void uiTemplateList(uiLayout *layout, - struct bContext *C, + const struct bContext *C, const char *listtype_name, const char *list_id, struct PointerRNA *dataptr, @@ -2496,7 +2496,7 @@ void uiTemplateList(uiLayout *layout, int columns, enum uiTemplateListFlags flags); struct uiList *uiTemplateList_ex(uiLayout *layout, - struct bContext *C, + const struct bContext *C, const char *listtype_name, const char *list_id, struct PointerRNA *dataptr, @@ -2566,7 +2566,7 @@ enum { UI_TEMPLATE_ASSET_DRAW_NO_LIBRARY = (1 << 2), }; void uiTemplateAssetView(struct uiLayout *layout, - struct bContext *C, + const struct bContext *C, const char *list_id, struct PointerRNA *asset_library_dataptr, const char *asset_library_propname, diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt index 07c3bfdafbf..e4a973a375e 100644 --- a/source/blender/editors/interface/CMakeLists.txt +++ b/source/blender/editors/interface/CMakeLists.txt @@ -21,21 +21,22 @@ set(INC ../../windowmanager ../../../../intern/glew-mx ../../../../intern/guardedalloc + ../../bmesh # RNA_prototypes.h ${CMAKE_BINARY_DIR}/source/blender/makesrna ) set(SRC - eyedroppers/interface_eyedropper.c eyedroppers/eyedropper_color.c eyedroppers/eyedropper_colorband.c eyedroppers/eyedropper_datablock.c eyedroppers/eyedropper_depth.c eyedroppers/eyedropper_driver.c eyedroppers/eyedropper_gpencil_color.c + eyedroppers/interface_eyedropper.c interface.cc interface_align.c - interface_anim.c + interface_anim.cc interface_button_group.c interface_context_menu.c interface_context_path.cc @@ -46,8 +47,8 @@ set(SRC interface_icons.c interface_icons_event.c interface_layout.c - interface_ops.c - interface_panel.c + interface_ops.cc + interface_panel.cc interface_query.cc interface_region_color_picker.cc interface_region_hud.cc @@ -56,16 +57,16 @@ set(SRC interface_region_popover.cc interface_region_popup.cc interface_region_search.cc - interface_region_tooltip.c + interface_region_tooltip.cc interface_regions.cc interface_style.cc interface_template_asset_view.cc interface_template_attribute_search.cc interface_template_list.cc interface_template_search_menu.cc - interface_template_search_operator.c + interface_template_search_operator.cc interface_templates.c - interface_undo.c + interface_undo.cc interface_utils.cc interface_widgets.c resources.c @@ -82,7 +83,7 @@ set(SRC eyedroppers/eyedropper_intern.h interface_intern.h - interface_regions_intern.h + interface_regions_intern.hh ) set(LIB diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index 2f9e69137ed..c076845af3c 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -1310,7 +1310,7 @@ static bool ui_but_event_operator_string_from_panel(const bContext *C, IDP_AddToGroup(prop_panel, IDP_New(IDP_INT, ®ion_type_val, "region_type")); for (int i = 0; i < 2; i++) { - /* FIXME(campbell): We can't reasonably search all configurations - long term. */ + /* FIXME(@campbellbarton): We can't reasonably search all configurations - long term. */ IDPropertyTemplate val = {0}; val.i = i; diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.cc index d7d1d3ce260..4da6cefd8de 100644 --- a/source/blender/editors/interface/interface_anim.c +++ b/source/blender/editors/interface/interface_anim.cc @@ -4,9 +4,9 @@ * \ingroup edinterface */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> +#include <cstdio> +#include <cstdlib> +#include <cstring> #include "MEM_guardedalloc.h" @@ -49,8 +49,14 @@ static FCurve *ui_but_get_fcurve( * but works well enough in typical cases */ const int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex; - return BKE_fcurve_find_by_rna_context_ui( - but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, adt, action, r_driven, r_special); + return BKE_fcurve_find_by_rna_context_ui(static_cast<bContext *>(but->block->evil_C), + &but->rnapoin, + but->rnaprop, + rnaindex, + adt, + action, + r_driven, + r_special); } void ui_but_anim_flag(uiBut *but, const AnimationEvalContext *anim_eval_context) @@ -93,7 +99,7 @@ void ui_but_anim_flag(uiBut *but, const AnimationEvalContext *anim_eval_context) } /* XXX: this feature is totally broken and useless with NLA */ - if (adt == NULL || adt->nla_tracks.first == NULL) { + if (adt == nullptr || adt->nla_tracks.first == nullptr) { const AnimationEvalContext remapped_context = BKE_animsys_eval_context_construct_at( anim_eval_context, cfra); if (fcurve_is_changed(but->rnapoin, but->rnaprop, fcu, &remapped_context)) { @@ -109,13 +115,13 @@ void ui_but_anim_flag(uiBut *but, const AnimationEvalContext *anim_eval_context) static uiBut *ui_but_anim_decorate_find_attached_button(uiButDecorator *but_decorate) { - uiBut *but_iter = NULL; + uiBut *but_iter = nullptr; BLI_assert(UI_but_is_decorator(&but_decorate->but)); BLI_assert(but_decorate->rnapoin.data && but_decorate->rnaprop); LISTBASE_CIRCULAR_BACKWARD_BEGIN ( - &but_decorate->but.block->buttons, but_iter, but_decorate->but.prev) { + uiBut *, &but_decorate->but.block->buttons, but_iter, but_decorate->but.prev) { if (but_iter != (uiBut *)but_decorate && ui_but_rna_equals_ex( but_iter, &but_decorate->rnapoin, but_decorate->rnaprop, but_decorate->rnaindex)) { @@ -123,9 +129,9 @@ static uiBut *ui_but_anim_decorate_find_attached_button(uiButDecorator *but_deco } } LISTBASE_CIRCULAR_BACKWARD_END( - &but_decorate->but.block->buttons, but_iter, but_decorate->but.prev); + uiBut *, &but_decorate->but.block->buttons, but_iter, but_decorate->but.prev); - return NULL; + return nullptr; } void ui_but_anim_decorate_update_from_flag(uiButDecorator *decorator_but) @@ -173,7 +179,7 @@ bool ui_but_anim_expression_get(uiBut *but, char *str, size_t maxlen) ChannelDriver *driver; bool driven, special; - fcu = ui_but_get_fcurve(but, NULL, NULL, &driven, &special); + fcu = ui_but_get_fcurve(but, nullptr, nullptr, &driven, &special); if (fcu && driven) { driver = fcu->driver; @@ -195,13 +201,13 @@ bool ui_but_anim_expression_set(uiBut *but, const char *str) ChannelDriver *driver; bool driven, special; - fcu = ui_but_get_fcurve(but, NULL, NULL, &driven, &special); + fcu = ui_but_get_fcurve(but, nullptr, nullptr, &driven, &special); if (fcu && driven) { driver = fcu->driver; if (driver && (driver->type == DRIVER_TYPE_PYTHON)) { - bContext *C = but->block->evil_C; + bContext *C = static_cast<bContext *>(but->block->evil_C); BLI_strncpy_utf8(driver->expression, str, sizeof(driver->expression)); @@ -213,7 +219,7 @@ bool ui_but_anim_expression_set(uiBut *but, const char *str) fcu->flag &= ~FCURVE_DISABLED; /* this notifier should update the Graph Editor and trigger depsgraph refresh? */ - WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME, NULL); + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME, nullptr); DEG_relations_tag_update(CTX_data_main(C)); @@ -226,14 +232,14 @@ bool ui_but_anim_expression_set(uiBut *but, const char *str) bool ui_but_anim_expression_create(uiBut *but, const char *str) { - bContext *C = but->block->evil_C; + bContext *C = static_cast<bContext *>(but->block->evil_C); ID *id; FCurve *fcu; char *path; bool ok = false; /* button must have RNA-pointer to a numeric-capable property */ - if (ELEM(NULL, but->rnapoin.data, but->rnaprop)) { + if (ELEM(nullptr, but->rnapoin.data, but->rnaprop)) { if (G.debug & G_DEBUG) { printf("ERROR: create expression failed - button has no RNA info attached\n"); } @@ -253,7 +259,7 @@ bool ui_but_anim_expression_create(uiBut *but, const char *str) /* FIXME: until materials can be handled by depsgraph, * don't allow drivers to be created for them */ id = but->rnapoin.owner_id; - if ((id == NULL) || (GS(id->name) == ID_MA) || (GS(id->name) == ID_TE)) { + if ((id == nullptr) || (GS(id->name) == ID_MA) || (GS(id->name) == ID_TE)) { if (G.debug & G_DEBUG) { printf("ERROR: create expression failed - invalid data-block for adding drivers (%p)\n", id); } @@ -262,7 +268,7 @@ bool ui_but_anim_expression_create(uiBut *but, const char *str) /* get path */ path = RNA_path_from_ID_to_property(&but->rnapoin, but->rnaprop); - if (path == NULL) { + if (path == nullptr) { return false; } @@ -282,7 +288,7 @@ bool ui_but_anim_expression_create(uiBut *but, const char *str) /* updates */ BKE_driver_invalidate_expression(driver, true, false); DEG_relations_tag_update(CTX_data_main(C)); - WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME, NULL); + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME, nullptr); ok = true; } } @@ -300,26 +306,26 @@ void ui_but_anim_autokey(bContext *C, uiBut *but, Scene *scene, float cfra) void ui_but_anim_copy_driver(bContext *C) { /* this operator calls UI_context_active_but_prop_get */ - WM_operator_name_call(C, "ANIM_OT_copy_driver_button", WM_OP_INVOKE_DEFAULT, NULL, NULL); + WM_operator_name_call(C, "ANIM_OT_copy_driver_button", WM_OP_INVOKE_DEFAULT, nullptr, nullptr); } void ui_but_anim_paste_driver(bContext *C) { /* this operator calls UI_context_active_but_prop_get */ - WM_operator_name_call(C, "ANIM_OT_paste_driver_button", WM_OP_INVOKE_DEFAULT, NULL, NULL); + WM_operator_name_call(C, "ANIM_OT_paste_driver_button", WM_OP_INVOKE_DEFAULT, nullptr, nullptr); } void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy)) { wmWindowManager *wm = CTX_wm_manager(C); - uiButDecorator *but_decorate = arg_but; + uiButDecorator *but_decorate = static_cast<uiButDecorator *>(arg_but); uiBut *but_anim = ui_but_anim_decorate_find_attached_button(but_decorate); if (!but_anim) { return; } - /* FIXME(campbell), swapping active pointer is weak. */ + /* FIXME(@campbellbarton): swapping active pointer is weak. */ SWAP(struct uiHandleButtonData *, but_anim->active, but_decorate->but.active); wm->op_undo_depth++; @@ -332,7 +338,7 @@ void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy) wmOperatorType *ot = WM_operatortype_find("ANIM_OT_keyframe_delete_button", false); WM_operator_properties_create_ptr(&props_ptr, ot); RNA_boolean_set(&props_ptr, "all", but_anim->rnaindex == -1); - WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr, NULL); + WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr, nullptr); WM_operator_properties_free(&props_ptr); } else { @@ -340,7 +346,7 @@ void ui_but_anim_decorate_cb(bContext *C, void *arg_but, void *UNUSED(arg_dummy) wmOperatorType *ot = WM_operatortype_find("ANIM_OT_keyframe_insert_button", false); WM_operator_properties_create_ptr(&props_ptr, ot); RNA_boolean_set(&props_ptr, "all", but_anim->rnaindex == -1); - WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr, NULL); + WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr, nullptr); WM_operator_properties_free(&props_ptr); } diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 80fd0cbe16e..5d4c8a342e2 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -8810,7 +8810,7 @@ void UI_context_active_but_prop_handle(bContext *C, const bool handle_undo) { uiBut *activebut = ui_context_rna_button_active(C); if (activebut) { - /* TODO(campbell): look into a better way to handle the button change + /* TODO(@campbellbarton): look into a better way to handle the button change * currently this is mainly so reset defaults works for the * operator redo panel. */ uiBlock *block = activebut->block; diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index c19e842aad8..5bb33576723 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -1824,7 +1824,7 @@ static void icon_draw_size(float x, } else if (di->type == ICON_TYPE_GEOM) { #ifdef USE_UI_TOOLBAR_HACK - /* TODO(campbell): scale icons up for toolbar, + /* TODO(@campbellbarton): scale icons up for toolbar, * we need a way to detect larger buttons and do this automatic. */ { float scale = (float)ICON_DEFAULT_HEIGHT_TOOLBAR / (float)ICON_DEFAULT_HEIGHT; @@ -1839,7 +1839,7 @@ static void icon_draw_size(float x, const bool geom_inverted = di->data.geom.inverted; /* This could re-generate often if rendered at different sizes in the one interface. - * TODO(campbell): support caching multiple sizes. */ + * TODO(@campbellbarton): support caching multiple sizes. */ ImBuf *ibuf = di->data.geom.image_cache; if ((ibuf == NULL) || (ibuf->x != w) || (ibuf->y != h) || (invert != geom_inverted)) { if (ibuf) { diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 03b9d03a6e3..d75d86c2665 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -468,6 +468,7 @@ typedef enum uiButtonGroupFlag { /** The buttons in this group are inside a panel header. */ UI_BUTTON_GROUP_PANEL_HEADER = (1 << 1), } uiButtonGroupFlag; +ENUM_OPERATORS(uiButtonGroupFlag, UI_BUTTON_GROUP_PANEL_HEADER); struct uiBlock { uiBlock *next, *prev; diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.cc index 4a5919864c7..2533a5454a5 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.cc @@ -5,7 +5,7 @@ * \ingroup edinterface */ -#include <string.h> +#include <cstring> #include "MEM_guardedalloc.h" @@ -128,7 +128,7 @@ static int copy_data_path_button_exec(bContext *C, wmOperator *op) /* try to create driver using property retrieved from UI */ UI_context_active_but_prop_get(C, &ptr, &prop, &index); - if (ptr.owner_id != NULL) { + if (ptr.owner_id != nullptr) { if (full_path) { if (prop) { path = RNA_path_full_property_py_ex(bmain, &ptr, prop, index, true); @@ -217,7 +217,7 @@ static int copy_as_driver_button_exec(bContext *C, wmOperator *op) if (ptr.owner_id && ptr.data && prop) { ID *id; - const int dim = RNA_property_array_dimension(&ptr, prop, NULL); + const int dim = RNA_property_array_dimension(&ptr, prop, nullptr); char *path = RNA_path_from_real_ID_to_property_index(bmain, &ptr, prop, dim, index, &id); if (path) { @@ -261,25 +261,25 @@ static bool copy_python_command_button_poll(bContext *C) { uiBut *but = UI_context_active_but_get(C); - if (but && (but->optype != NULL)) { - return 1; + if (but && (but->optype != nullptr)) { + return true; } - return 0; + return false; } static int copy_python_command_button_exec(bContext *C, wmOperator *UNUSED(op)) { uiBut *but = UI_context_active_but_get(C); - if (but && (but->optype != NULL)) { + if (but && (but->optype != nullptr)) { PointerRNA *opptr; char *str; opptr = UI_but_operator_ptr_get(but); /* allocated when needed, the button owns it */ - str = WM_operator_pystring_ex(C, NULL, false, true, but->optype, opptr); + str = WM_operator_pystring_ex(C, nullptr, false, true, but->optype, opptr); - WM_clipboard_text_set(str, 0); + WM_clipboard_text_set(str, false); MEM_freeN(str); @@ -391,7 +391,8 @@ static void UI_OT_reset_default_button(wmOperatorType *ot) ot->flag = 0; /* properties */ - RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array"); + RNA_def_boolean( + ot->srna, "all", true, "All", "Reset to default values all elements of the array"); } /** \} */ @@ -530,7 +531,7 @@ static EnumPropertyItem override_type_items[] = { 0, "Factor", "Store factor to linked data value (useful e.g. for scale)"}, - {0, NULL, 0, NULL, NULL}, + {0, nullptr, 0, nullptr, nullptr}, }; static bool override_type_set_button_poll(bContext *C) @@ -581,16 +582,16 @@ static int override_type_set_button_exec(bContext *C, wmOperator *op) /* try to reset the nominated setting to its default value */ UI_context_active_but_prop_get(C, &ptr, &prop, &index); - BLI_assert(ptr.owner_id != NULL); + BLI_assert(ptr.owner_id != nullptr); if (all) { index = -1; } IDOverrideLibraryPropertyOperation *opop = RNA_property_override_property_operation_get( - CTX_data_main(C), &ptr, prop, operation, index, true, NULL, &created); + CTX_data_main(C), &ptr, prop, operation, index, true, nullptr, &created); - if (opop == NULL) { + if (opop == nullptr) { /* Sometimes e.g. RNA cannot generate a path to the given property. */ BKE_reportf(op->reports, RPT_WARNING, "Failed to create the override operation"); return OPERATOR_CANCELLED; @@ -601,7 +602,7 @@ static int override_type_set_button_exec(bContext *C, wmOperator *op) } /* Outliner e.g. has to be aware of this change. */ - WM_main_add_notifier(NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL); + WM_main_add_notifier(NC_WM | ND_LIB_OVERRIDE_CHANGED, nullptr); return operator_button_property_finish(C, &ptr, prop); } @@ -634,7 +635,8 @@ static void UI_OT_override_type_set_button(wmOperatorType *ot) ot->flag = OPTYPE_UNDO; /* properties */ - RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array"); + RNA_def_boolean( + ot->srna, "all", true, "All", "Reset to default values all elements of the array"); ot->prop = RNA_def_enum(ot->srna, "type", override_type_items, @@ -671,8 +673,8 @@ static int override_remove_button_exec(bContext *C, wmOperator *op) ID *id = ptr.owner_id; IDOverrideLibraryProperty *oprop = RNA_property_override_property_find(bmain, &ptr, prop, &id); - BLI_assert(oprop != NULL); - BLI_assert(id != NULL && id->override_library != NULL); + BLI_assert(oprop != nullptr); + BLI_assert(id != nullptr && id->override_library != nullptr); const bool is_template = ID_IS_OVERRIDE_LIBRARY_TEMPLATE(id); @@ -691,8 +693,8 @@ static int override_remove_button_exec(bContext *C, wmOperator *op) /* Remove override operation for given item, * add singular operations for the other items as needed. */ IDOverrideLibraryPropertyOperation *opop = BKE_lib_override_library_property_operation_find( - oprop, NULL, NULL, index, index, false, &is_strict_find); - BLI_assert(opop != NULL); + oprop, nullptr, nullptr, index, index, false, &is_strict_find); + BLI_assert(opop != nullptr); if (!is_strict_find) { /* No specific override operation, we have to get generic one, * and create item-specific override operations for all but given index, @@ -700,7 +702,7 @@ static int override_remove_button_exec(bContext *C, wmOperator *op) for (int idx = RNA_property_array_length(&ptr, prop); idx--;) { if (idx != index) { BKE_lib_override_library_property_operation_get( - oprop, opop->operation, NULL, NULL, idx, idx, true, NULL, NULL); + oprop, opop->operation, nullptr, nullptr, idx, idx, true, nullptr, nullptr); } } } @@ -721,7 +723,7 @@ static int override_remove_button_exec(bContext *C, wmOperator *op) } /* Outliner e.g. has to be aware of this change. */ - WM_main_add_notifier(NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL); + WM_main_add_notifier(NC_WM | ND_LIB_OVERRIDE_CHANGED, nullptr); return operator_button_property_finish(C, &ptr, prop); } @@ -741,7 +743,8 @@ static void UI_OT_override_remove_button(wmOperatorType *ot) ot->flag = OPTYPE_UNDO; /* properties */ - RNA_def_boolean(ot->srna, "all", 1, "All", "Reset to default values all elements of the array"); + RNA_def_boolean( + ot->srna, "all", true, "All", "Reset to default values all elements of the array"); } /** \} */ @@ -750,8 +753,8 @@ static void UI_OT_override_remove_button(wmOperatorType *ot) /** \name Copy To Selected Operator * \{ */ -#define NOT_NULL(assignment) ((assignment) != NULL) -#define NOT_RNA_NULL(assignment) ((assignment).data != NULL) +#define NOT_NULL(assignment) ((assignment) != nullptr) +#define NOT_RNA_NULL(assignment) ((assignment).data != nullptr) static void ui_context_selected_bones_via_pose(bContext *C, ListBase *r_lb) { @@ -760,7 +763,7 @@ static void ui_context_selected_bones_via_pose(bContext *C, ListBase *r_lb) if (!BLI_listbase_is_empty(&lb)) { LISTBASE_FOREACH (CollectionPointerLink *, link, &lb) { - bPoseChannel *pchan = link->ptr.data; + bPoseChannel *pchan = static_cast<bPoseChannel *>(link->ptr.data); RNA_pointer_create(link->ptr.owner_id, &RNA_Bone, pchan->bone, &link->ptr); } } @@ -776,9 +779,9 @@ bool UI_context_copy_to_selected_list(bContext *C, char **r_path) { *r_use_path_from_id = false; - *r_path = NULL; + *r_path = nullptr; /* special case for bone constraints */ - char *path_from_bone = NULL; + char *path_from_bone = nullptr; /* Remove links from the collection list which don't contain 'prop'. */ bool ensure_list_items_contain_prop = false; @@ -792,29 +795,32 @@ bool UI_context_copy_to_selected_list(bContext *C, */ if (!RNA_property_is_idprop(prop) && RNA_struct_is_a(ptr->type, &RNA_PropertyGroup)) { PointerRNA owner_ptr; - char *idpath = NULL; + char *idpath = nullptr; /* First, check the active PoseBone and PoseBone->Bone. */ if (NOT_RNA_NULL( owner_ptr = CTX_data_pointer_get_type(C, "active_pose_bone", &RNA_PoseBone))) { - if (NOT_NULL(idpath = RNA_path_from_struct_to_idproperty(&owner_ptr, ptr->data))) { + if (NOT_NULL(idpath = RNA_path_from_struct_to_idproperty( + &owner_ptr, static_cast<IDProperty *>(ptr->data)))) { *r_lb = CTX_data_collection_get(C, "selected_pose_bones"); } else { - bPoseChannel *pchan = owner_ptr.data; + bPoseChannel *pchan = static_cast<bPoseChannel *>(owner_ptr.data); RNA_pointer_create(owner_ptr.owner_id, &RNA_Bone, pchan->bone, &owner_ptr); - if (NOT_NULL(idpath = RNA_path_from_struct_to_idproperty(&owner_ptr, ptr->data))) { + if (NOT_NULL(idpath = RNA_path_from_struct_to_idproperty( + &owner_ptr, static_cast<IDProperty *>(ptr->data)))) { ui_context_selected_bones_via_pose(C, r_lb); } } } - if (idpath == NULL) { + if (idpath == nullptr) { /* Check the active EditBone if in edit mode. */ if (NOT_RNA_NULL( owner_ptr = CTX_data_pointer_get_type_silent(C, "active_bone", &RNA_EditBone)) && - NOT_NULL(idpath = RNA_path_from_struct_to_idproperty(&owner_ptr, ptr->data))) { + NOT_NULL(idpath = RNA_path_from_struct_to_idproperty( + &owner_ptr, static_cast<IDProperty *>(ptr->data)))) { *r_lb = CTX_data_collection_get(C, "selected_editable_bones"); } @@ -867,30 +873,30 @@ bool UI_context_copy_to_selected_list(bContext *C, } else if (RNA_struct_is_a(ptr->type, &RNA_Constraint) && (path_from_bone = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_PoseBone)) != - NULL) { + nullptr) { *r_lb = CTX_data_collection_get(C, "selected_pose_bones"); *r_path = path_from_bone; } else if (RNA_struct_is_a(ptr->type, &RNA_Node) || RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) { - ListBase lb = {NULL, NULL}; - char *path = NULL; - bNode *node = NULL; + ListBase lb = {nullptr, nullptr}; + char *path = nullptr; + bNode *node = nullptr; /* Get the node we're editing */ if (RNA_struct_is_a(ptr->type, &RNA_NodeSocket)) { bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - bNodeSocket *sock = ptr->data; - if (nodeFindNode(ntree, sock, &node, NULL)) { - if ((path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Node)) != NULL) { + bNodeSocket *sock = static_cast<bNodeSocket *>(ptr->data); + if (nodeFindNode(ntree, sock, &node, nullptr)) { + if ((path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Node)) != nullptr) { /* we're good! */ } else { - node = NULL; + node = nullptr; } } } else { - node = ptr->data; + node = static_cast<bNode *>(ptr->data); } /* Now filter by type */ @@ -898,7 +904,7 @@ bool UI_context_copy_to_selected_list(bContext *C, lb = CTX_data_collection_get(C, "selected_nodes"); LISTBASE_FOREACH_MUTABLE (CollectionPointerLink *, link, &lb) { - bNode *node_data = link->ptr.data; + bNode *node_data = static_cast<bNode *>(link->ptr.data); if (node_data->type != node->type) { BLI_remlink(&lb, link); @@ -929,17 +935,17 @@ bool UI_context_copy_to_selected_list(bContext *C, LISTBASE_FOREACH (CollectionPointerLink *, link, &lb) { Object *ob = (Object *)link->ptr.owner_id; if (ob->data) { - ID *id_data = ob->data; + ID *id_data = static_cast<ID *>(ob->data); id_data->tag |= LIB_TAG_DOIT; } } LISTBASE_FOREACH_MUTABLE (CollectionPointerLink *, link, &lb) { Object *ob = (Object *)link->ptr.owner_id; - ID *id_data = ob->data; + ID *id_data = static_cast<ID *>(ob->data); - if ((id_data == NULL) || (id_data->tag & LIB_TAG_DOIT) == 0 || ID_IS_LINKED(id_data) || - (GS(id_data->name) != id_code)) { + if ((id_data == nullptr) || (id_data->tag & LIB_TAG_DOIT) == 0 || + ID_IS_LINKED(id_data) || (GS(id_data->name) != id_code)) { BLI_remlink(&lb, link); MEM_freeN(link); } @@ -961,7 +967,8 @@ bool UI_context_copy_to_selected_list(bContext *C, /* Sequencer's ID is scene :/ */ /* Try to recursively find an RNA_Sequence ancestor, * to handle situations like T41062... */ - if ((*r_path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Sequence)) != NULL) { + if ((*r_path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Sequence)) != + nullptr) { /* Special case when we do this for 'Sequence.lock'. * (if the sequence is locked, it won't be in "selected_editable_sequences"). */ const char *prop_id = RNA_property_identifier(prop); @@ -975,7 +982,7 @@ bool UI_context_copy_to_selected_list(bContext *C, ensure_list_items_contain_prop = true; } } - return (*r_path != NULL); + return (*r_path != nullptr); } else { return false; @@ -1013,13 +1020,13 @@ bool UI_context_copy_to_selected_check(PointerRNA *ptr, if (use_path_from_id) { /* Path relative to ID. */ - lprop = NULL; + lprop = nullptr; RNA_id_pointer_create(ptr_link->owner_id, &idptr); RNA_path_resolve_property(&idptr, path, &lptr, &lprop); } else if (path) { /* Path relative to elements from list. */ - lprop = NULL; + lprop = nullptr; RNA_path_resolve_property(ptr_link, path, &lptr, &lprop); } else { @@ -1034,7 +1041,7 @@ bool UI_context_copy_to_selected_check(PointerRNA *ptr, /* Skip non-existing properties on link. This was previously covered with the `lprop != prop` * check but we are now more permissive when it comes to ID properties, see below. */ - if (lprop == NULL) { + if (lprop == nullptr) { return false; } @@ -1105,13 +1112,13 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll) UI_context_active_but_prop_get(C, &ptr, &prop, &index); /* if there is a valid property that is editable... */ - if (ptr.data == NULL || prop == NULL) { + if (ptr.data == nullptr || prop == nullptr) { return false; } - char *path = NULL; + char *path = nullptr; bool use_path_from_id; - ListBase lb = {NULL}; + ListBase lb = {nullptr}; if (!UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path)) { return false; @@ -1198,7 +1205,7 @@ static bool jump_to_target_ptr(bContext *C, PointerRNA ptr, const bool poll) /* Verify pointer type. */ char bone_name[MAXBONENAME]; - const StructRNA *target_type = NULL; + const StructRNA *target_type = nullptr; if (ELEM(ptr.type, &RNA_EditBone, &RNA_PoseBone, &RNA_Bone)) { RNA_string_get(&ptr, "name", bone_name); @@ -1210,13 +1217,13 @@ static bool jump_to_target_ptr(bContext *C, PointerRNA ptr, const bool poll) target_type = &RNA_Object; } - if (target_type == NULL) { + if (target_type == nullptr) { return false; } /* Find the containing Object. */ ViewLayer *view_layer = CTX_data_view_layer(C); - Base *base = NULL; + Base *base = nullptr; const short id_type = GS(ptr.owner_id->name); if (id_type == ID_OB) { base = BKE_view_layer_base_find(view_layer, (Object *)ptr.owner_id); @@ -1226,7 +1233,7 @@ static bool jump_to_target_ptr(bContext *C, PointerRNA ptr, const bool poll) } bool ok = false; - if ((base == NULL) || ((target_type == &RNA_Bone) && (base->object->type != OB_ARMATURE))) { + if ((base == nullptr) || ((target_type == &RNA_Bone) && (base->object->type != OB_ARMATURE))) { /* pass */ } else if (poll) { @@ -1278,13 +1285,14 @@ static bool jump_to_target_button(bContext *C, bool poll) if (type == PROP_STRING) { const uiBut *but = UI_context_active_but_get(C); const uiButSearch *search_but = (but->type == UI_BTYPE_SEARCH_MENU) ? (uiButSearch *)but : - NULL; + nullptr; if (search_but && search_but->items_update_fn == ui_rna_collection_search_update_fn) { - uiRNACollectionSearch *coll_search = search_but->arg; + uiRNACollectionSearch *coll_search = static_cast<uiRNACollectionSearch *>(search_but->arg); char str_buf[MAXBONENAME]; - char *str_ptr = RNA_property_string_get_alloc(&ptr, prop, str_buf, sizeof(str_buf), NULL); + char *str_ptr = RNA_property_string_get_alloc( + &ptr, prop, str_buf, sizeof(str_buf), nullptr); int found = RNA_property_collection_lookup_string( &coll_search->search_ptr, coll_search->search_prop, str_ptr, &target_ptr); @@ -1342,39 +1350,39 @@ static void UI_OT_jump_to_target_button(wmOperatorType *ot) /* EditSource Utility funcs and operator, * NOTE: this includes utility functions and button matching checks. */ -typedef struct uiEditSourceStore { +struct uiEditSourceStore { uiBut but_orig; GHash *hash; -} uiEditSourceStore; +}; -typedef struct uiEditSourceButStore { +struct uiEditSourceButStore { char py_dbg_fn[FILE_MAX]; int py_dbg_line_number; -} uiEditSourceButStore; +}; /* should only ever be set while the edit source operator is running */ -static struct uiEditSourceStore *ui_editsource_info = NULL; +static uiEditSourceStore *ui_editsource_info = nullptr; bool UI_editsource_enable_check(void) { - return (ui_editsource_info != NULL); + return (ui_editsource_info != nullptr); } static void ui_editsource_active_but_set(uiBut *but) { - BLI_assert(ui_editsource_info == NULL); + BLI_assert(ui_editsource_info == nullptr); - ui_editsource_info = MEM_callocN(sizeof(uiEditSourceStore), __func__); + ui_editsource_info = MEM_cnew<uiEditSourceStore>(__func__); memcpy(&ui_editsource_info->but_orig, but, sizeof(uiBut)); ui_editsource_info->hash = BLI_ghash_ptr_new(__func__); } -static void ui_editsource_active_but_clear(void) +static void ui_editsource_active_but_clear() { - BLI_ghash_free(ui_editsource_info->hash, NULL, MEM_freeN); + BLI_ghash_free(ui_editsource_info->hash, nullptr, MEM_freeN); MEM_freeN(ui_editsource_info); - ui_editsource_info = NULL; + ui_editsource_info = nullptr; } static bool ui_editsource_uibut_match(uiBut *but_a, uiBut *but_b) @@ -1395,11 +1403,14 @@ static bool ui_editsource_uibut_match(uiBut *but_a, uiBut *but_b) return false; } +extern "C" { +void PyC_FileAndNum_Safe(const char **r_filename, int *r_lineno); +} + void UI_editsource_active_but_test(uiBut *but) { - extern void PyC_FileAndNum_Safe(const char **r_filename, int *r_lineno); - struct uiEditSourceButStore *but_store = MEM_callocN(sizeof(uiEditSourceButStore), __func__); + uiEditSourceButStore *but_store = MEM_cnew<uiEditSourceButStore>(__func__); const char *fn; int line_number = -1; @@ -1424,9 +1435,10 @@ void UI_editsource_active_but_test(uiBut *but) void UI_editsource_but_replace(const uiBut *old_but, uiBut *new_but) { - uiEditSourceButStore *but_store = BLI_ghash_lookup(ui_editsource_info->hash, old_but); + uiEditSourceButStore *but_store = static_cast<uiEditSourceButStore *>( + BLI_ghash_lookup(ui_editsource_info->hash, old_but)); if (but_store) { - BLI_ghash_remove(ui_editsource_info->hash, old_but, NULL, NULL); + BLI_ghash_remove(ui_editsource_info->hash, old_but, nullptr, nullptr); BLI_ghash_insert(ui_editsource_info->hash, new_but, but_store); } } @@ -1436,8 +1448,8 @@ static int editsource_text_edit(bContext *C, const char filepath[FILE_MAX], const int line) { - struct Main *bmain = CTX_data_main(C); - Text *text = NULL; + Main *bmain = CTX_data_main(C); + Text *text = nullptr; /* Developers may wish to copy-paste to an external editor. */ printf("%s:%d\n", filepath, line); @@ -1449,11 +1461,11 @@ static int editsource_text_edit(bContext *C, } } - if (text == NULL) { + if (text == nullptr) { text = BKE_text_load(bmain, filepath, BKE_main_blendfile_path(bmain)); } - if (text == NULL) { + if (text == nullptr) { BKE_reportf(op->reports, RPT_WARNING, "File '%s' cannot be opened", filepath); return OPERATOR_CANCELLED; } @@ -1477,7 +1489,7 @@ static int editsource_exec(bContext *C, wmOperator *op) if (but) { GHashIterator ghi; - struct uiEditSourceButStore *but_store = NULL; + uiEditSourceButStore *but_store = nullptr; ARegion *region = CTX_wm_region(C); int ret; @@ -1496,9 +1508,9 @@ static int editsource_exec(bContext *C, wmOperator *op) for (BLI_ghashIterator_init(&ghi, ui_editsource_info->hash); BLI_ghashIterator_done(&ghi) == false; BLI_ghashIterator_step(&ghi)) { - uiBut *but_key = BLI_ghashIterator_getKey(&ghi); + uiBut *but_key = static_cast<uiBut *>(BLI_ghashIterator_getKey(&ghi)); if (but_key && ui_editsource_uibut_match(&ui_editsource_info->but_orig, but_key)) { - but_store = BLI_ghashIterator_getValue(&ghi); + but_store = static_cast<uiEditSourceButStore *>(BLI_ghashIterator_getValue(&ghi)); break; } } @@ -1569,7 +1581,7 @@ static void edittranslation_find_po_file(const char *root, /* Now try without the second iso code part (_ES in es_ES). */ { - const char *tc = NULL; + const char *tc = nullptr; size_t szt = 0; tstr[0] = '\0'; @@ -1603,7 +1615,7 @@ static void edittranslation_find_po_file(const char *root, static int edittranslation_exec(bContext *C, wmOperator *op) { uiBut *but = UI_context_active_but_get(C); - if (but == NULL) { + if (but == nullptr) { BKE_report(op->reports, RPT_ERROR, "Active button not found"); return OPERATOR_CANCELLED; } @@ -1614,16 +1626,16 @@ static int edittranslation_exec(bContext *C, wmOperator *op) const char *root = U.i18ndir; const char *uilng = BLT_lang_get(); - uiStringInfo but_label = {BUT_GET_LABEL, NULL}; - uiStringInfo rna_label = {BUT_GET_RNA_LABEL, NULL}; - uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL}; - uiStringInfo but_tip = {BUT_GET_TIP, NULL}; - uiStringInfo rna_tip = {BUT_GET_RNA_TIP, NULL}; - uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, NULL}; - uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, NULL}; - uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, NULL}; - uiStringInfo rna_enum = {BUT_GET_RNAENUM_IDENTIFIER, NULL}; - uiStringInfo rna_ctxt = {BUT_GET_RNA_LABEL_CONTEXT, NULL}; + uiStringInfo but_label = {BUT_GET_LABEL, nullptr}; + uiStringInfo rna_label = {BUT_GET_RNA_LABEL, nullptr}; + uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, nullptr}; + uiStringInfo but_tip = {BUT_GET_TIP, nullptr}; + uiStringInfo rna_tip = {BUT_GET_RNA_TIP, nullptr}; + uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, nullptr}; + uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, nullptr}; + uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, nullptr}; + uiStringInfo rna_enum = {BUT_GET_RNAENUM_IDENTIFIER, nullptr}; + uiStringInfo rna_ctxt = {BUT_GET_RNA_LABEL_CONTEXT, nullptr}; if (!BLI_is_dir(root)) { BKE_report(op->reports, @@ -1632,8 +1644,8 @@ static int edittranslation_exec(bContext *C, wmOperator *op) "Directory' path to a valid directory"); return OPERATOR_CANCELLED; } - ot = WM_operatortype_find(EDTSRC_I18N_OP_NAME, 0); - if (ot == NULL) { + ot = WM_operatortype_find(EDTSRC_I18N_OP_NAME, false); + if (ot == nullptr) { BKE_reportf(op->reports, RPT_ERROR, "Could not find operator '%s'! Please enable ui_translate add-on " @@ -1662,7 +1674,7 @@ static int edittranslation_exec(bContext *C, wmOperator *op) &rna_prop, &rna_enum, &rna_ctxt, - NULL); + nullptr); WM_operator_properties_create_ptr(&ptr, ot); RNA_string_set(&ptr, "lang", uilng); @@ -1677,7 +1689,7 @@ static int edittranslation_exec(bContext *C, wmOperator *op) RNA_string_set(&ptr, "rna_prop", rna_prop.strinfo); RNA_string_set(&ptr, "rna_enum", rna_enum.strinfo); RNA_string_set(&ptr, "rna_ctxt", rna_ctxt.strinfo); - const int ret = WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, NULL); + const int ret = WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, nullptr); /* Clean up */ if (but_label.strinfo) { @@ -1737,7 +1749,7 @@ static int reloadtranslation_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)) { BLT_lang_init(); BLF_cache_clear(); - BLT_lang_set(NULL); + BLT_lang_set(nullptr); UI_reinit_font(); return OPERATOR_FINISHED; } @@ -1764,13 +1776,13 @@ static int ui_button_press_invoke(bContext *C, wmOperator *op, const wmEvent *ev bScreen *screen = CTX_wm_screen(C); const bool skip_depressed = RNA_boolean_get(op->ptr, "skip_depressed"); ARegion *region_prev = CTX_wm_region(C); - ARegion *region = screen ? BKE_screen_find_region_xy(screen, RGN_TYPE_ANY, event->xy) : NULL; + ARegion *region = screen ? BKE_screen_find_region_xy(screen, RGN_TYPE_ANY, event->xy) : nullptr; - if (region == NULL) { + if (region == nullptr) { region = region_prev; } - if (region == NULL) { + if (region == nullptr) { return OPERATOR_PASS_THROUGH; } @@ -1778,7 +1790,7 @@ static int ui_button_press_invoke(bContext *C, wmOperator *op, const wmEvent *ev uiBut *but = UI_context_active_but_get(C); CTX_wm_region_set(C, region_prev); - if (but == NULL) { + if (but == nullptr) { return OPERATOR_PASS_THROUGH; } if (skip_depressed && (but->flag & (UI_SELECT | UI_SELECT_DRAW))) { @@ -1791,7 +1803,7 @@ static int ui_button_press_invoke(bContext *C, wmOperator *op, const wmEvent *ev UI_but_execute(C, region, but); - but->optype = but_optype; + but->optype = static_cast<wmOperatorType *>(but_optype); WM_event_add_mousemove(CTX_wm_window(C)); @@ -1807,7 +1819,7 @@ static void UI_OT_button_execute(wmOperatorType *ot) ot->invoke = ui_button_press_invoke; ot->flag = OPTYPE_INTERNAL; - RNA_def_boolean(ot->srna, "skip_depressed", 0, "Skip Depressed", ""); + RNA_def_boolean(ot->srna, "skip_depressed", false, "Skip Depressed", ""); } /** \} */ @@ -1853,21 +1865,21 @@ bool UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED( ARegion *region = CTX_wm_region(C); if (UI_but_active_drop_color(C)) { - return 1; + return true; } if (sima && (sima->mode == SI_MODE_PAINT) && sima->image && (region && region->regiontype == RGN_TYPE_WINDOW)) { - return 1; + return true; } } - return 0; + return false; } void UI_drop_color_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop) { - uiDragColorHandle *drag_info = drag->poin; + uiDragColorHandle *drag_info = static_cast<uiDragColorHandle *>(drag->poin); RNA_float_set_array(drop->ptr, "color", drag_info->color); RNA_boolean_set(drop->ptr, "gamma", drag_info->gamma_corrected); @@ -1876,7 +1888,7 @@ void UI_drop_color_copy(bContext *UNUSED(C), wmDrag *drag, wmDropBox *drop) static int drop_color_invoke(bContext *C, wmOperator *op, const wmEvent *event) { ARegion *region = CTX_wm_region(C); - uiBut *but = NULL; + uiBut *but = nullptr; float color[4]; bool gamma; @@ -1933,8 +1945,10 @@ static void UI_OT_drop_color(wmOperatorType *ot) ot->invoke = drop_color_invoke; ot->flag = OPTYPE_INTERNAL; - RNA_def_float_color(ot->srna, "color", 3, NULL, 0.0, FLT_MAX, "Color", "Source color", 0.0, 1.0); - RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected"); + RNA_def_float_color( + ot->srna, "color", 3, nullptr, 0.0, FLT_MAX, "Color", "Source color", 0.0, 1.0); + RNA_def_boolean( + ot->srna, "gamma", false, "Gamma Corrected", "The source color is gamma corrected"); } /** \} */ @@ -1964,7 +1978,7 @@ static bool drop_name_poll(bContext *C) static int drop_name_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) { uiBut *but = UI_but_active_drop_name_button(C); - char *str = RNA_string_get_alloc(op->ptr, "string", NULL, 0, NULL); + char *str = RNA_string_get_alloc(op->ptr, "string", nullptr, 0, nullptr); if (str) { ui_but_set_string_interactive(C, but, str); @@ -1985,7 +1999,7 @@ static void UI_OT_drop_name(wmOperatorType *ot) ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL; RNA_def_string( - ot->srna, "string", NULL, 0, "String", "The string value to drop into the button"); + ot->srna, "string", nullptr, 0, "String", "The string value to drop into the button"); } /** \} */ @@ -2003,7 +2017,7 @@ static bool ui_list_focused_poll(bContext *C) const wmWindow *win = CTX_wm_window(C); const uiList *list = UI_list_find_mouse_over(region, win->eventstate); - return list != NULL; + return list != nullptr; } /** @@ -2026,7 +2040,7 @@ static int ui_list_start_filter_invoke(bContext *C, wmOperator *UNUSED(op), cons ARegion *region = CTX_wm_region(C); uiList *list = UI_list_find_mouse_over(region, event); /* Poll should check. */ - BLI_assert(list != NULL); + BLI_assert(list != nullptr); if (ui_list_unhide_filter_options(list)) { ui_region_redraw_immediately(C, region); @@ -2061,7 +2075,7 @@ static bool ui_view_drop_poll(bContext *C) const ARegion *region = CTX_wm_region(C); const uiViewItemHandle *hovered_item = UI_region_views_find_item_at(region, win->eventstate->xy); - return hovered_item != NULL; + return hovered_item != nullptr; } static int ui_view_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) @@ -2073,7 +2087,8 @@ static int ui_view_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEven const ARegion *region = CTX_wm_region(C); uiViewItemHandle *hovered_item = UI_region_views_find_item_at(region, event->xy); - if (!UI_view_item_drop_handle(C, hovered_item, event->customdata)) { + if (!UI_view_item_drop_handle( + C, hovered_item, static_cast<const ListBase *>(event->customdata))) { return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH; } @@ -2107,7 +2122,7 @@ static bool ui_view_item_rename_poll(bContext *C) { const ARegion *region = CTX_wm_region(C); const uiViewItemHandle *active_item = UI_region_views_find_active_item(region); - return active_item != NULL && UI_view_item_can_rename(active_item); + return active_item != nullptr && UI_view_item_can_rename(active_item); } static int ui_view_item_rename_exec(bContext *C, wmOperator *UNUSED(op)) @@ -2144,8 +2159,8 @@ static void UI_OT_view_item_rename(wmOperatorType *ot) static bool ui_drop_material_poll(bContext *C) { PointerRNA ptr = CTX_data_pointer_get_type(C, "object", &RNA_Object); - Object *ob = ptr.data; - if (ob == NULL) { + const Object *ob = static_cast<const Object *>(ptr.data); + if (ob == nullptr) { return false; } @@ -2163,12 +2178,12 @@ static int ui_drop_material_exec(bContext *C, wmOperator *op) Material *ma = (Material *)WM_operator_properties_id_lookup_from_name_or_session_uuid( bmain, op->ptr, ID_MA); - if (ma == NULL) { + if (ma == nullptr) { return OPERATOR_CANCELLED; } PointerRNA ptr = CTX_data_pointer_get_type(C, "object", &RNA_Object); - Object *ob = ptr.data; + Object *ob = static_cast<Object *>(ptr.data); BLI_assert(ob); PointerRNA mat_slot = CTX_data_pointer_get_type(C, "material_slot", &RNA_MaterialSlot); @@ -2176,14 +2191,14 @@ static int ui_drop_material_exec(bContext *C, wmOperator *op) const int target_slot = RNA_int_get(&mat_slot, "slot_index") + 1; /* only drop grease pencil material on grease pencil objects */ - if ((ma->gp_style != NULL) && (ob->type != OB_GPENCIL)) { + if ((ma->gp_style != nullptr) && (ob->type != OB_GPENCIL)) { return OPERATOR_CANCELLED; } BKE_object_material_assign(bmain, ob, ma, target_slot, BKE_MAT_ASSIGN_USERPREF); WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob); - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, nullptr); WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma); DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.cc index d4a9a4ca4cd..dc6a0fecb73 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.cc @@ -8,10 +8,10 @@ /* a full doc with API notes can be found in * bf-blender/trunk/blender/doc/guides/interface_API.txt */ -#include <ctype.h> -#include <math.h> -#include <stdlib.h> -#include <string.h> +#include <cctype> +#include <cmath> +#include <cstdlib> +#include <cstring> #include "MEM_guardedalloc.h" @@ -57,7 +57,7 @@ #define ANIMATION_TIME 0.30 #define ANIMATION_INTERVAL 0.02 -typedef enum uiPanelRuntimeFlag { +enum uiPanelRuntimeFlag { PANEL_LAST_ADDED = (1 << 0), PANEL_ACTIVE = (1 << 2), PANEL_WAS_ACTIVE = (1 << 3), @@ -78,22 +78,22 @@ typedef enum uiPanelRuntimeFlag { PANEL_IS_DRAG_DROP = (1 << 10), /** Draw a border with the active color around the panel. */ PANEL_ACTIVE_BORDER = (1 << 11), -} uiPanelRuntimeFlag; +}; /* The state of the mouse position relative to the panel. */ -typedef enum uiPanelMouseState { +enum uiPanelMouseState { PANEL_MOUSE_OUTSIDE, /** Mouse is not in the panel. */ PANEL_MOUSE_INSIDE_CONTENT, /** Mouse is in the actual panel content. */ PANEL_MOUSE_INSIDE_HEADER, /** Mouse is in the panel header. */ -} uiPanelMouseState; +}; -typedef enum uiHandlePanelState { +enum uiHandlePanelState { PANEL_STATE_DRAG, PANEL_STATE_ANIMATION, PANEL_STATE_EXIT, -} uiHandlePanelState; +}; -typedef struct uiHandlePanelData { +struct uiHandlePanelData { uiHandlePanelState state; /* Animation. */ @@ -104,17 +104,17 @@ typedef struct uiHandlePanelData { int startx, starty; int startofsx, startofsy; float start_cur_xmin, start_cur_ymin; -} uiHandlePanelData; +}; -typedef struct PanelSort { +struct PanelSort { Panel *panel; int new_offset_x; int new_offset_y; -} PanelSort; +}; static void panel_set_expansion_from_list_data(const bContext *C, Panel *panel); static int get_panel_real_size_y(const Panel *panel); -static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelState state); +static void panel_activate_state(const bContext *C, Panel *panel, const uiHandlePanelState state); static int compare_panel(const void *a, const void *b); static bool panel_type_context_poll(ARegion *region, const PanelType *panel_type, @@ -155,7 +155,7 @@ static bool panel_active_animation_changed(ListBase *lb, /* Detect animation. */ if (panel->activedata) { - uiHandlePanelData *data = panel->activedata; + uiHandlePanelData *data = static_cast<uiHandlePanelData *>(panel->activedata); if (data->state == PANEL_STATE_ANIMATION) { *r_panel_animation = panel; } @@ -178,7 +178,7 @@ static bool panel_active_animation_changed(ListBase *lb, static bool properties_space_needs_realign(const ScrArea *area, const ARegion *region) { if (area->spacetype == SPACE_PROPERTIES && region->regiontype == RGN_TYPE_WINDOW) { - SpaceProperties *sbuts = area->spacedata.first; + const SpaceProperties *sbuts = static_cast<SpaceProperties *>(area->spacedata.first); if (sbuts->mainbo != sbuts->mainb) { return true; @@ -190,14 +190,14 @@ static bool properties_space_needs_realign(const ScrArea *area, const ARegion *r static bool panels_need_realign(const ScrArea *area, ARegion *region, Panel **r_panel_animation) { - *r_panel_animation = NULL; + *r_panel_animation = nullptr; if (properties_space_needs_realign(area, region)) { return true; } /* Detect if a panel was added or removed. */ - Panel *panel_animation = NULL; + Panel *panel_animation = nullptr; bool no_animation = false; if (panel_active_animation_changed(®ion->panels, &panel_animation, &no_animation)) { return true; @@ -225,7 +225,7 @@ static Panel *panel_add_instanced(ARegion *region, PanelType *panel_type, PointerRNA *custom_data) { - Panel *panel = MEM_callocN(sizeof(Panel), __func__); + Panel *panel = MEM_cnew<Panel>(__func__); panel->type = panel_type; BLI_strncpy(panel->panelname, panel_type->idname, sizeof(panel->panelname)); @@ -235,7 +235,7 @@ static Panel *panel_add_instanced(ARegion *region, /* Add the panel's children too. Although they aren't instanced panels, we can still use this * function to create them, as UI_panel_begin does other things we don't need to do. */ LISTBASE_FOREACH (LinkData *, child, &panel_type->children) { - PanelType *child_type = child->data; + PanelType *child_type = static_cast<PanelType *>(child->data); panel_add_instanced(region, &panel->children, child_type, custom_data); } @@ -265,12 +265,12 @@ Panel *UI_panel_add_instanced(const bContext *C, { ARegionType *region_type = region->type; - PanelType *panel_type = BLI_findstring( - ®ion_type->paneltypes, panel_idname, offsetof(PanelType, idname)); + PanelType *panel_type = static_cast<PanelType *>( + BLI_findstring(®ion_type->paneltypes, panel_idname, offsetof(PanelType, idname))); - if (panel_type == NULL) { + if (panel_type == nullptr) { printf("Panel type '%s' not found.\n", panel_idname); - return NULL; + return nullptr; } Panel *new_panel = panel_add_instanced(region, panels, panel_type, custom_data); @@ -314,14 +314,14 @@ void UI_panels_free_instanced(const bContext *C, ARegion *region) { /* Delete panels with the instanced flag. */ LISTBASE_FOREACH_MUTABLE (Panel *, panel, ®ion->panels) { - if ((panel->type != NULL) && (panel->type->flag & PANEL_TYPE_INSTANCED)) { + if ((panel->type != nullptr) && (panel->type->flag & PANEL_TYPE_INSTANCED)) { /* Make sure the panel's handler is removed before deleting it. */ - if (C != NULL && panel->activedata != NULL) { + if (C != nullptr && panel->activedata != nullptr) { panel_activate_state(C, panel, PANEL_STATE_EXIT); } /* Free panel's custom data. */ - if (panel->runtime.custom_data_ptr != NULL) { + if (panel->runtime.custom_data_ptr != nullptr) { MEM_freeN(panel->runtime.custom_data_ptr); } @@ -335,28 +335,28 @@ bool UI_panel_list_matches_data(ARegion *region, ListBase *data, uiListPanelIDFromDataFunc panel_idname_func) { - /* Check for NULL data. */ + /* Check for nullptr data. */ int data_len = 0; - Link *data_link = NULL; - if (data == NULL) { + Link *data_link = nullptr; + if (data == nullptr) { data_len = 0; - data_link = NULL; + data_link = nullptr; } else { data_len = BLI_listbase_count(data); - data_link = data->first; + data_link = static_cast<Link *>(data->first); } int i = 0; LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { - if (panel->type != NULL && panel->type->flag & PANEL_TYPE_INSTANCED) { + if (panel->type != nullptr && panel->type->flag & PANEL_TYPE_INSTANCED) { /* The panels were reordered by drag and drop. */ if (panel->flag & PNL_INSTANCED_LIST_ORDER_CHANGED) { return false; } /* We reached the last data item before the last instanced panel. */ - if (data_link == NULL) { + if (data_link == nullptr) { return false; } @@ -383,15 +383,15 @@ bool UI_panel_list_matches_data(ARegion *region, static void reorder_instanced_panel_list(bContext *C, ARegion *region, Panel *drag_panel) { /* Without a type we cannot access the reorder callback. */ - if (drag_panel->type == NULL) { + if (drag_panel->type == nullptr) { return; } /* Don't reorder if this instanced panel doesn't support drag and drop reordering. */ - if (drag_panel->type->reorder == NULL) { + if (drag_panel->type->reorder == nullptr) { return; } - char *context = NULL; + char *context = nullptr; if (!UI_panel_category_is_visible(region)) { context = drag_panel->type->context; } @@ -415,7 +415,8 @@ static void reorder_instanced_panel_list(bContext *C, ARegion *region, Panel *dr BLI_assert(start_index != -1); /* The drag panel should definitely be in the list. */ /* Sort the matching instanced panels by their display order. */ - PanelSort *panel_sort = MEM_callocN(list_panels_len * sizeof(*panel_sort), __func__); + PanelSort *panel_sort = static_cast<PanelSort *>( + MEM_callocN(list_panels_len * sizeof(*panel_sort), __func__)); PanelSort *sort_index = panel_sort; LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { if (panel->type) { @@ -452,7 +453,7 @@ static void reorder_instanced_panel_list(bContext *C, ARegion *region, Panel *dr /* Finally, move this panel's list item to the new index in its list. */ drag_panel->type->reorder(C, drag_panel, move_to_index); - CTX_store_set(C, NULL); + CTX_store_set(C, nullptr); } /** @@ -480,9 +481,9 @@ static bool panel_set_expand_from_list_data_recursive(Panel *panel, short flag, */ static void panel_set_expansion_from_list_data(const bContext *C, Panel *panel) { - BLI_assert(panel->type != NULL); + BLI_assert(panel->type != nullptr); BLI_assert(panel->type->flag & PANEL_TYPE_INSTANCED); - if (panel->type->get_list_data_expand_flag == NULL) { + if (panel->type->get_list_data_expand_flag == nullptr) { /* Instanced panel doesn't support loading expansion. */ return; } @@ -504,7 +505,7 @@ static void region_panels_set_expansion_from_list_data(const bContext *C, ARegio LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { if (panel->runtime_flag & PANEL_ACTIVE) { PanelType *panel_type = panel->type; - if (panel_type != NULL && panel->type->flag & PANEL_TYPE_INSTANCED) { + if (panel_type != nullptr && panel->type->flag & PANEL_TYPE_INSTANCED) { panel_set_expansion_from_list_data(C, panel); } } @@ -537,7 +538,7 @@ static void set_panels_list_data_expand_flag(const bContext *C, const ARegion *r { LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { PanelType *panel_type = panel->type; - if (panel_type == NULL) { + if (panel_type == nullptr) { continue; } @@ -563,11 +564,11 @@ static bool panel_custom_data_active_get(const Panel *panel) { /* The caller should make sure the panel is active and has a type. */ BLI_assert(UI_panel_is_active(panel)); - BLI_assert(panel->type != NULL); + BLI_assert(panel->type != nullptr); if (panel->type->active_property[0] != '\0') { PointerRNA *ptr = UI_panel_custom_data_get(panel); - if (ptr != NULL && !RNA_pointer_is_null(ptr)) { + if (ptr != nullptr && !RNA_pointer_is_null(ptr)) { return RNA_boolean_get(ptr, panel->type->active_property); } } @@ -579,12 +580,12 @@ static void panel_custom_data_active_set(Panel *panel) { /* Since the panel is interacted with, it should be active and have a type. */ BLI_assert(UI_panel_is_active(panel)); - BLI_assert(panel->type != NULL); + BLI_assert(panel->type != nullptr); if (panel->type->active_property[0] != '\0') { PointerRNA *ptr = UI_panel_custom_data_get(panel); - BLI_assert(RNA_struct_find_property(ptr, panel->type->active_property) != NULL); - if (ptr != NULL && !RNA_pointer_is_null(ptr)) { + BLI_assert(RNA_struct_find_property(ptr, panel->type->active_property) != nullptr); + if (ptr != nullptr && !RNA_pointer_is_null(ptr)) { RNA_boolean_set(ptr, panel->type->active_property, true); } } @@ -617,7 +618,7 @@ static void panel_set_runtime_flag_recursive(Panel *panel, short flag, bool valu static void panels_collapse_all(ARegion *region, const Panel *from_panel) { const bool has_category_tabs = UI_panel_category_is_visible(region); - const char *category = has_category_tabs ? UI_panel_category_active_get(region, false) : NULL; + const char *category = has_category_tabs ? UI_panel_category_active_get(region, false) : nullptr; const PanelType *from_pt = from_panel->type; LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { @@ -659,7 +660,7 @@ Panel *UI_panel_find_by_type(ListBase *lb, const PanelType *pt) return panel; } } - return NULL; + return nullptr; } Panel *UI_panel_begin( @@ -668,10 +669,10 @@ Panel *UI_panel_begin( Panel *panel_last; const char *drawname = CTX_IFACE_(pt->translation_context, pt->label); const char *idname = pt->idname; - const bool newpanel = (panel == NULL); + const bool newpanel = (panel == nullptr); if (newpanel) { - panel = MEM_callocN(sizeof(Panel), __func__); + panel = MEM_cnew<Panel>(__func__); panel->type = pt; BLI_strncpy(panel->panelname, idname, sizeof(panel->panelname)); @@ -701,7 +702,7 @@ Panel *UI_panel_begin( /* If a new panel is added, we insert it right after the panel that was last added. * This way new panels are inserted in the right place between versions. */ - for (panel_last = lb->first; panel_last; panel_last = panel_last->next) { + for (panel_last = static_cast<Panel *>(lb->first); panel_last; panel_last = panel_last->next) { if (panel_last->runtime_flag & PANEL_LAST_ADDED) { BLI_remlink(lb, panel); BLI_insertlinkafter(lb, panel_last, panel); @@ -755,7 +756,7 @@ void UI_panel_header_buttons_end(Panel *panel) /* A button group should always be created in #UI_panel_header_buttons_begin. */ BLI_assert(!BLI_listbase_is_empty(&block->button_groups)); - uiButtonGroup *button_group = block->button_groups.last; + uiButtonGroup *button_group = static_cast<uiButtonGroup *>(block->button_groups.last); button_group->flag &= ~UI_BUTTON_GROUP_LOCK; @@ -770,7 +771,7 @@ void UI_panel_header_buttons_end(Panel *panel) /* Always add a new button group. Although this may result in many empty groups, without it, * new buttons in the panel body not protected with a #ui_block_new_button_group call would * end up in the panel header group. */ - ui_block_new_button_group(block, 0); + ui_block_new_button_group(block, (uiButtonGroupFlag)0); } } @@ -867,7 +868,7 @@ void ui_panel_tag_search_filter_match(Panel *panel) static void panel_matches_search_filter_recursive(const Panel *panel, bool *filter_matches) { - *filter_matches |= panel->runtime_flag & PANEL_SEARCH_FILTER_MATCH; + *filter_matches |= bool(panel->runtime_flag & PANEL_SEARCH_FILTER_MATCH); /* If the panel has no match we need to make sure that its children are too. */ if (!*filter_matches) { @@ -893,7 +894,7 @@ static void panel_set_expansion_from_search_filter_recursive(const bContext *C, { /* This has to run on inactive panels that may not have a type, * but we can prevent running on header-less panels in some cases. */ - if (panel->type == NULL || !(panel->type->flag & PANEL_TYPE_NO_HEADER)) { + if (panel->type == nullptr || !(panel->type->flag & PANEL_TYPE_NO_HEADER)) { SET_FLAG_FROM_TEST(panel->runtime_flag, use_search_closed, PANEL_USE_CLOSED_FROM_SEARCH); } @@ -926,9 +927,9 @@ static void region_panels_set_expansion_from_search_filter(const bContext *C, static void panel_remove_invisible_layouts_recursive(Panel *panel, const Panel *parent_panel) { uiBlock *block = panel->runtime.block; - BLI_assert(block != NULL); + BLI_assert(block != nullptr); BLI_assert(block->active); - if (parent_panel != NULL && UI_panel_is_closed(parent_panel)) { + if (parent_panel != nullptr && UI_panel_is_closed(parent_panel)) { /* The parent panel is closed, so this panel can be completely removed. */ UI_block_set_search_only(block, true); LISTBASE_FOREACH (uiBut *, but, &block->buttons) { @@ -944,7 +945,7 @@ static void panel_remove_invisible_layouts_recursive(Panel *panel, const Panel * continue; } LISTBASE_FOREACH (LinkData *, link, &button_group->buttons) { - uiBut *but = link->data; + uiBut *but = static_cast<uiBut *>(link->data); but->flag |= UI_HIDDEN; } } @@ -952,7 +953,7 @@ static void panel_remove_invisible_layouts_recursive(Panel *panel, const Panel * LISTBASE_FOREACH (Panel *, child_panel, &panel->children) { if (child_panel->runtime_flag & PANEL_ACTIVE) { - BLI_assert(child_panel->runtime.block != NULL); + BLI_assert(child_panel->runtime.block != nullptr); panel_remove_invisible_layouts_recursive(child_panel, panel); } } @@ -962,8 +963,8 @@ static void region_panels_remove_invisible_layouts(ARegion *region) { LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { if (panel->runtime_flag & PANEL_ACTIVE) { - BLI_assert(panel->runtime.block != NULL); - panel_remove_invisible_layouts_recursive(panel, NULL); + BLI_assert(panel->runtime.block != nullptr); + panel_remove_invisible_layouts_recursive(panel, nullptr); } } } @@ -1054,7 +1055,7 @@ static void panel_draw_highlight_border(const Panel *panel, const rcti *rect, const rcti *header_rect) { - const bool is_subpanel = panel->type->parent != NULL; + const bool is_subpanel = panel->type->parent != nullptr; if (is_subpanel) { return; } @@ -1064,18 +1065,15 @@ static void panel_draw_highlight_border(const Panel *panel, const float radius = (btheme->tui.panel_roundness * U.widget_unit * 0.5f) / aspect; UI_draw_roundbox_corner_set(UI_CNR_ALL); + rctf box_rect; + box_rect.xmin = rect->xmin; + box_rect.xmax = rect->xmax; + box_rect.ymin = UI_panel_is_closed(panel) ? header_rect->ymin : rect->ymin; + box_rect.ymax = header_rect->ymax; + float color[4]; UI_GetThemeColor4fv(TH_SELECT_ACTIVE, color); - UI_draw_roundbox_4fv( - &(const rctf){ - .xmin = rect->xmin, - .xmax = rect->xmax, - .ymin = UI_panel_is_closed(panel) ? header_rect->ymin : rect->ymin, - .ymax = header_rect->ymax, - }, - false, - radius, - color); + UI_draw_roundbox_4fv(&box_rect, false, radius, color); } static void panel_draw_aligned_widgets(const uiStyle *style, @@ -1086,19 +1084,18 @@ static void panel_draw_aligned_widgets(const uiStyle *style, const bool show_background, const bool region_search_filter_active) { - const bool is_subpanel = panel->type->parent != NULL; + const bool is_subpanel = panel->type->parent != nullptr; const uiFontStyle *fontstyle = (is_subpanel) ? &style->widgetlabel : &style->paneltitle; const int header_height = BLI_rcti_size_y(header_rect); const int scaled_unit = round_fl_to_int(UI_UNIT_X / aspect); - /* Offset triangle and text to the right for subpanels. */ - const rcti widget_rect = { - .xmin = header_rect->xmin + (is_subpanel ? scaled_unit * 0.7f : 0), - .xmax = header_rect->xmax, - .ymin = header_rect->ymin, - .ymax = header_rect->ymax, - }; + /* Offset triangle and text to the right for sub-panels. */ + rcti widget_rect; + widget_rect.xmin = header_rect->xmin + (is_subpanel ? scaled_unit * 0.7f : 0); + widget_rect.xmax = header_rect->xmax; + widget_rect.ymin = header_rect->ymin; + widget_rect.ymax = header_rect->ymax; uchar title_color[4]; panel_title_color_get(panel, show_background, region_search_filter_active, title_color); @@ -1121,20 +1118,16 @@ static void panel_draw_aligned_widgets(const uiStyle *style, /* Draw text label. */ if (panel->drawname[0] != '\0') { - const rcti title_rect = { - .xmin = widget_rect.xmin + (panel->labelofs / aspect) + scaled_unit * 1.1f, - .xmax = widget_rect.xmax, - .ymin = widget_rect.ymin - 2.0f / aspect, - .ymax = widget_rect.ymax, - }; - UI_fontstyle_draw(fontstyle, - &title_rect, - panel->drawname, - sizeof(panel->drawname), - title_color, - &(struct uiFontStyleDraw_Params){ - .align = UI_STYLE_TEXT_LEFT, - }); + rcti title_rect; + title_rect.xmin = widget_rect.xmin + (panel->labelofs / aspect) + scaled_unit * 1.1f; + title_rect.xmax = widget_rect.xmax; + title_rect.ymin = widget_rect.ymin - 2.0f / aspect; + title_rect.ymax = widget_rect.ymax; + + uiFontStyleDraw_Params params{}; + params.align = UI_STYLE_TEXT_LEFT; + UI_fontstyle_draw( + fontstyle, &title_rect, panel->drawname, sizeof(panel->drawname), title_color, ¶ms); } /* Draw the pin icon. */ @@ -1177,7 +1170,7 @@ static void panel_draw_aligned_backdrop(const Panel *panel, const rcti *rect, const rcti *header_rect) { - const bool is_subpanel = panel->type->parent != NULL; + const bool is_subpanel = panel->type->parent != nullptr; const bool is_open = !UI_panel_is_closed(panel); if (is_subpanel && !is_open) { @@ -1197,16 +1190,12 @@ static void panel_draw_aligned_backdrop(const Panel *panel, UI_draw_roundbox_corner_set(is_open ? UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT : UI_CNR_ALL); UI_GetThemeColor4fv((is_subpanel ? TH_PANEL_SUB_BACK : TH_PANEL_BACK), panel_backcolor); - UI_draw_roundbox_4fv( - &(const rctf){ - .xmin = rect->xmin, - .xmax = rect->xmax, - .ymin = rect->ymin, - .ymax = rect->ymax, - }, - true, - radius, - panel_backcolor); + rctf box_rect; + box_rect.xmin = rect->xmin; + box_rect.xmax = rect->xmax; + box_rect.ymin = rect->ymin; + box_rect.ymax = rect->ymax; + UI_draw_roundbox_4fv(&box_rect, true, radius, panel_backcolor); } /* Panel header backdrops for non sub-panels. */ @@ -1217,16 +1206,12 @@ static void panel_draw_aligned_backdrop(const Panel *panel, UI_draw_roundbox_corner_set(is_open ? UI_CNR_TOP_RIGHT | UI_CNR_TOP_LEFT : UI_CNR_ALL); /* Change the width a little bit to line up with the sides. */ - UI_draw_roundbox_4fv( - &(const rctf){ - .xmin = rect->xmin, - .xmax = rect->xmax, - .ymin = header_rect->ymin, - .ymax = header_rect->ymax, - }, - true, - radius, - panel_headercolor); + rctf box_rect; + box_rect.xmin = rect->xmin; + box_rect.xmax = rect->xmax; + box_rect.ymin = header_rect->ymin; + box_rect.ymax = header_rect->ymax; + UI_draw_roundbox_4fv(&box_rect, true, radius, panel_headercolor); } GPU_blend(GPU_BLEND_NONE); @@ -1247,7 +1232,7 @@ void ui_draw_aligned_panel(const uiStyle *style, rect->xmin, rect->xmax, rect->ymax, - rect->ymax + floor(PNL_HEADER / block->aspect + 0.001f), + rect->ymax + (int)floor(PNL_HEADER / block->aspect + 0.001f), }; if (show_background) { @@ -1300,7 +1285,7 @@ bool UI_panel_should_show_background(const ARegion *region, const PanelType *pan 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); + const bool is_left = RGN_ALIGN_ENUM_FROM_MASK(region->alignment) != RGN_ALIGN_RIGHT; View2D *v2d = ®ion->v2d; const uiStyle *style = UI_style_get(); const uiFontStyle *fstyle = &style->widget; @@ -1463,26 +1448,17 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active) { /* Draw filled rectangle and outline for tab. */ UI_draw_roundbox_corner_set(roundboxtype); - UI_draw_roundbox_4fv( - &(const rctf){ - .xmin = rct->xmin, - .xmax = rct->xmax, - .ymin = rct->ymin, - .ymax = rct->ymax, - }, - true, - tab_curve_radius, - is_active ? theme_col_tab_active : theme_col_tab_inactive); - UI_draw_roundbox_4fv( - &(const rctf){ - .xmin = rct->xmin, - .xmax = rct->xmax, - .ymin = rct->ymin, - .ymax = rct->ymax, - }, - false, - tab_curve_radius, - theme_col_tab_outline); + rctf box_rect; + box_rect.xmin = rct->xmin; + box_rect.xmax = rct->xmax; + box_rect.ymin = rct->ymin; + box_rect.ymax = rct->ymax; + + UI_draw_roundbox_4fv(&box_rect, + true, + tab_curve_radius, + is_active ? theme_col_tab_active : theme_col_tab_inactive); + UI_draw_roundbox_4fv(&box_rect, false, tab_curve_radius, theme_col_tab_outline); /* Disguise the outline on one side to join the tab to the panel. */ pos = GPU_vertformat_attr_add( @@ -1502,7 +1478,7 @@ void UI_panel_category_draw_all(ARegion *region, const char *category_id_active) if (do_scaletabs) { category_draw_len = BLF_width_to_strlen( - fontid, category_id_draw, category_draw_len, category_width, NULL); + fontid, category_id_draw, category_draw_len, category_width, nullptr); } BLF_position(fontid, rct->xmax - text_v_ofs, rct->ymin + tab_v_pad_text, 0.0f); @@ -1660,7 +1636,7 @@ static bool uiAlignPanelStep(ARegion *region, const float factor, const bool dra LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { if (panel->runtime_flag & PANEL_ACTIVE) { /* These panels should have types since they are currently displayed to the user. */ - BLI_assert(panel->type != NULL); + BLI_assert(panel->type != nullptr); active_panels_len++; } } @@ -1669,7 +1645,8 @@ static bool uiAlignPanelStep(ARegion *region, const float factor, const bool dra } /* Sort panels. */ - PanelSort *panel_sort = MEM_mallocN(sizeof(PanelSort) * active_panels_len, __func__); + PanelSort *panel_sort = static_cast<PanelSort *>( + MEM_mallocN(sizeof(PanelSort) * active_panels_len, __func__)); { PanelSort *ps = panel_sort; LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { @@ -1791,7 +1768,7 @@ static void ui_panels_size(ARegion *region, int *r_x, int *r_y) static void ui_do_animate(bContext *C, Panel *panel) { - uiHandlePanelData *data = panel->activedata; + uiHandlePanelData *data = static_cast<uiHandlePanelData *>(panel->activedata); ARegion *region = CTX_wm_region(C); float fac = (PIL_check_seconds_timer() - data->starttime) / ANIMATION_TIME; @@ -1856,7 +1833,7 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y) LISTBASE_FOREACH (Panel *, panel, ®ion->panels) { if (panel->runtime_flag & PANEL_ACTIVE) { - BLI_assert(panel->runtime.block != NULL); + BLI_assert(panel->runtime.block != nullptr); panel_calculate_size_recursive(region, panel); } } @@ -1892,7 +1869,7 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y) #define DRAG_REGION_PAD (PNL_HEADER * 0.5) static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel) { - uiHandlePanelData *data = panel->activedata; + uiHandlePanelData *data = static_cast<uiHandlePanelData *>(panel->activedata); ARegion *region = CTX_wm_region(C); /* Keep the drag position in the region with a small pad to keep the panel visible. */ @@ -1942,14 +1919,14 @@ static uiPanelMouseState ui_panel_mouse_state_get(const uiBlock *block, return PANEL_MOUSE_OUTSIDE; } -typedef struct uiPanelDragCollapseHandle { +struct uiPanelDragCollapseHandle { bool was_first_open; int xy_init[2]; -} uiPanelDragCollapseHandle; +}; static void ui_panel_drag_collapse_handler_remove(bContext *UNUSED(C), void *userdata) { - uiPanelDragCollapseHandle *dragcol_data = userdata; + uiPanelDragCollapseHandle *dragcol_data = static_cast<uiPanelDragCollapseHandle *>(userdata); MEM_freeN(dragcol_data); } @@ -1960,11 +1937,11 @@ static void ui_panel_drag_collapse(const bContext *C, ARegion *region = CTX_wm_region(C); LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { - float xy_a_block[2] = {UNPACK2(dragcol_data->xy_init)}; - float xy_b_block[2] = {UNPACK2(xy_dst)}; + float xy_a_block[2] = {(float)dragcol_data->xy_init[0], (float)dragcol_data->xy_init[1]}; + float xy_b_block[2] = {(float)xy_dst[0], (float)xy_dst[1]}; Panel *panel = block->panel; - if (panel == NULL || (panel->type && (panel->type->flag & PANEL_TYPE_NO_HEADER))) { + if (panel == nullptr || (panel->type && (panel->type->flag & PANEL_TYPE_NO_HEADER))) { continue; } const int oldflag = panel->flag; @@ -2006,7 +1983,7 @@ static void ui_panel_drag_collapse(const bContext *C, static int ui_panel_drag_collapse_handler(bContext *C, const wmEvent *event, void *userdata) { wmWindow *win = CTX_wm_window(C); - uiPanelDragCollapseHandle *dragcol_data = userdata; + uiPanelDragCollapseHandle *dragcol_data = static_cast<uiPanelDragCollapseHandle *>(userdata); short retval = WM_UI_HANDLER_CONTINUE; switch (event->type) { @@ -2037,7 +2014,7 @@ static void ui_panel_drag_collapse_handler_add(const bContext *C, const bool was { wmWindow *win = CTX_wm_window(C); const wmEvent *event = win->eventstate; - uiPanelDragCollapseHandle *dragcol_data = MEM_mallocN(sizeof(*dragcol_data), __func__); + uiPanelDragCollapseHandle *dragcol_data = MEM_new<uiPanelDragCollapseHandle>(__func__); dragcol_data->was_first_open = was_open; copy_v2_v2_int(dragcol_data->xy_init, event->xy); @@ -2066,10 +2043,10 @@ static void ui_handle_panel_header(const bContext *C, Panel *panel = block->panel; ARegion *region = CTX_wm_region(C); - BLI_assert(panel->type != NULL); + BLI_assert(panel->type != nullptr); BLI_assert(!(panel->type->flag & PANEL_TYPE_NO_HEADER)); - const bool is_subpanel = (panel->type->parent != NULL); + const bool is_subpanel = (panel->type->parent != nullptr); const bool use_pin = UI_panel_category_is_visible(region) && UI_panel_can_be_pinned(panel); const bool show_pin = use_pin && (panel->flag & PNL_PIN); const bool show_drag = !is_subpanel; @@ -2102,8 +2079,8 @@ static void ui_handle_panel_header(const bContext *C, else { /* If a panel has sub-panels and it's open, toggle the expansion * of the sub-panels (based on the expansion of the first sub-panel). */ - Panel *first_child = panel->children.first; - BLI_assert(first_child != NULL); + Panel *first_child = static_cast<Panel *>(panel->children.first); + BLI_assert(first_child != nullptr); panel_set_flag_recursive(panel, PNL_CLOSED, !UI_panel_is_closed(first_child)); panel->flag |= PNL_CLOSED; } @@ -2115,7 +2092,7 @@ static void ui_handle_panel_header(const bContext *C, ui_panel_drag_collapse_handler_add(C, UI_panel_is_closed(panel)); } - /* Set panel custom data (modifier) active when expanding subpanels, but not top-level + /* Set panel custom data (modifier) active when expanding sub-panels, but not top-level * panels to allow collapsing and expanding without setting the active element. */ if (is_subpanel) { panel_custom_data_active_set(panel); @@ -2157,13 +2134,14 @@ bool UI_panel_category_is_visible(const ARegion *region) PanelCategoryDyn *UI_panel_category_find(const ARegion *region, const char *idname) { - return BLI_findstring(®ion->panels_category, idname, offsetof(PanelCategoryDyn, idname)); + return static_cast<PanelCategoryDyn *>( + BLI_findstring(®ion->panels_category, idname, offsetof(PanelCategoryDyn, idname))); } PanelCategoryStack *UI_panel_category_active_find(ARegion *region, const char *idname) { - return BLI_findstring( - ®ion->panels_category_active, idname, offsetof(PanelCategoryStack, idname)); + return static_cast<PanelCategoryStack *>(BLI_findstring( + ®ion->panels_category_active, idname, offsetof(PanelCategoryStack, idname))); } static void ui_panel_category_active_set(ARegion *region, const char *idname, bool fallback) @@ -2175,7 +2153,7 @@ static void ui_panel_category_active_set(ARegion *region, const char *idname, bo BLI_remlink(lb, pc_act); } else { - pc_act = MEM_callocN(sizeof(PanelCategoryStack), __func__); + pc_act = MEM_cnew<PanelCategoryStack>(__func__); BLI_strncpy(pc_act->idname, idname, sizeof(pc_act->idname)); } @@ -2226,14 +2204,14 @@ const char *UI_panel_category_active_get(ARegion *region, bool set_fallback) } if (set_fallback) { - PanelCategoryDyn *pc_dyn = region->panels_category.first; + PanelCategoryDyn *pc_dyn = static_cast<PanelCategoryDyn *>(region->panels_category.first); if (pc_dyn) { ui_panel_category_active_set(region, pc_dyn->idname, true); return pc_dyn->idname; } } - return NULL; + return nullptr; } static PanelCategoryDyn *panel_categories_find_mouse_over(ARegion *region, const wmEvent *event) @@ -2244,12 +2222,12 @@ static PanelCategoryDyn *panel_categories_find_mouse_over(ARegion *region, const } } - return NULL; + return nullptr; } void UI_panel_category_add(ARegion *region, const char *name) { - PanelCategoryDyn *pc_dyn = MEM_callocN(sizeof(*pc_dyn), __func__); + PanelCategoryDyn *pc_dyn = MEM_cnew<PanelCategoryDyn>(__func__); BLI_addtail(®ion->panels_category, pc_dyn); BLI_strncpy(pc_dyn->idname, name, sizeof(pc_dyn->idname)); @@ -2294,7 +2272,8 @@ static int ui_handle_panel_category_cycling(const wmEvent *event, pc_dyn = backwards ? pc_dyn->prev : pc_dyn->next; if (!pc_dyn) { /* Proper cyclic behavior, back to first/last category (only used for ctrl+tab). */ - pc_dyn = backwards ? region->panels_category.last : region->panels_category.first; + pc_dyn = backwards ? static_cast<PanelCategoryDyn *>(region->panels_category.last) : + static_cast<PanelCategoryDyn *>(region->panels_category.first); } } @@ -2359,11 +2338,11 @@ int ui_handler_panel_region(bContext *C, return retval; } - const bool region_has_active_button = (ui_region_find_active_but(region) != NULL); + const bool region_has_active_button = (ui_region_find_active_but(region) != nullptr); LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { Panel *panel = block->panel; - if (panel == NULL || panel->type == NULL) { + if (panel == nullptr || panel->type == nullptr) { continue; } /* We can't expand or collapse panels without headers, they would disappear. */ @@ -2434,10 +2413,10 @@ void UI_panel_context_pointer_set(Panel *panel, const char *name, PointerRNA *pt void UI_panel_custom_data_set(Panel *panel, PointerRNA *custom_data) { - BLI_assert(panel->type != NULL); + BLI_assert(panel->type != nullptr); /* Free the old custom data, which should be shared among all of the panel's sub-panels. */ - if (panel->runtime.custom_data_ptr != NULL) { + if (panel->runtime.custom_data_ptr != nullptr) { MEM_freeN(panel->runtime.custom_data_ptr); } @@ -2455,7 +2434,7 @@ PointerRNA *UI_region_panel_custom_data_under_cursor(const bContext *C, const wm LISTBASE_FOREACH (uiBlock *, block, ®ion->uiblocks) { Panel *panel = block->panel; - if (panel == NULL) { + if (panel == nullptr) { continue; } @@ -2468,12 +2447,12 @@ PointerRNA *UI_region_panel_custom_data_under_cursor(const bContext *C, const wm } } - return NULL; + return nullptr; } bool UI_panel_can_be_pinned(const Panel *panel) { - return (panel->type->parent == NULL) && !(panel->type->flag & PANEL_TYPE_INSTANCED); + return (panel->type->parent == nullptr) && !(panel->type->flag & PANEL_TYPE_INSTANCED); } /** \} */ @@ -2485,8 +2464,8 @@ bool UI_panel_can_be_pinned(const Panel *panel) /* NOTE: this is modal handler and should not swallow events for animation. */ static int ui_handler_panel(bContext *C, const wmEvent *event, void *userdata) { - Panel *panel = userdata; - uiHandlePanelData *data = panel->activedata; + Panel *panel = static_cast<Panel *>(userdata); + uiHandlePanelData *data = static_cast<uiHandlePanelData *>(panel->activedata); /* Verify if we can stop. */ if (event->type == LEFTMOUSE && event->val == KM_RELEASE) { @@ -2506,7 +2485,7 @@ static int ui_handler_panel(bContext *C, const wmEvent *event, void *userdata) } } - data = panel->activedata; + data = static_cast<uiHandlePanelData *>(panel->activedata); if (data && data->state == PANEL_STATE_ANIMATION) { return WM_UI_HANDLER_CONTINUE; @@ -2516,7 +2495,7 @@ static int ui_handler_panel(bContext *C, const wmEvent *event, void *userdata) static void ui_handler_remove_panel(bContext *C, void *userdata) { - Panel *panel = userdata; + Panel *panel = static_cast<Panel *>(userdata); panel_activate_state(C, panel, PANEL_STATE_EXIT); } @@ -2527,13 +2506,13 @@ static void panel_handle_data_ensure(const bContext *C, Panel *panel, const uiHandlePanelState state) { - if (panel->activedata == NULL) { + if (panel->activedata == nullptr) { panel->activedata = MEM_callocN(sizeof(uiHandlePanelData), __func__); WM_event_add_ui_handler( C, &win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, panel, 0); } - uiHandlePanelData *data = panel->activedata; + uiHandlePanelData *data = static_cast<uiHandlePanelData *>(panel->activedata); data->animtimer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, ANIMATION_INTERVAL); @@ -2554,11 +2533,11 @@ static void panel_handle_data_ensure(const bContext *C, */ static void panel_activate_state(const bContext *C, Panel *panel, const uiHandlePanelState state) { - uiHandlePanelData *data = panel->activedata; + uiHandlePanelData *data = static_cast<uiHandlePanelData *>(panel->activedata); wmWindow *win = CTX_wm_window(C); ARegion *region = CTX_wm_region(C); - if (data != NULL && data->state == state) { + if (data != nullptr && data->state == state) { return; } @@ -2582,15 +2561,15 @@ static void panel_activate_state(const bContext *C, Panel *panel, const uiHandle else if (state == PANEL_STATE_EXIT) { panel_set_runtime_flag_recursive(panel, PANEL_IS_DRAG_DROP, false); - BLI_assert(data != NULL); + BLI_assert(data != nullptr); if (data->animtimer) { WM_event_remove_timer(CTX_wm_manager(C), win, data->animtimer); - data->animtimer = NULL; + data->animtimer = nullptr; } MEM_freeN(data); - panel->activedata = NULL; + panel->activedata = nullptr; WM_event_remove_ui_handler( &win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, panel, false); diff --git a/source/blender/editors/interface/interface_region_menu_pie.cc b/source/blender/editors/interface/interface_region_menu_pie.cc index 8572e938b30..becdfaf4e25 100644 --- a/source/blender/editors/interface/interface_region_menu_pie.cc +++ b/source/blender/editors/interface/interface_region_menu_pie.cc @@ -37,7 +37,7 @@ #include "ED_screen.h" #include "interface_intern.h" -#include "interface_regions_intern.h" +#include "interface_regions_intern.hh" /* -------------------------------------------------------------------- */ /** \name Pie Menu diff --git a/source/blender/editors/interface/interface_region_menu_popup.cc b/source/blender/editors/interface/interface_region_menu_popup.cc index a22f7218203..0647e1a4a70 100644 --- a/source/blender/editors/interface/interface_region_menu_popup.cc +++ b/source/blender/editors/interface/interface_region_menu_popup.cc @@ -39,7 +39,7 @@ #include "ED_screen.h" #include "interface_intern.h" -#include "interface_regions_intern.h" +#include "interface_regions_intern.hh" /* -------------------------------------------------------------------- */ /** \name Utility Functions diff --git a/source/blender/editors/interface/interface_region_popover.cc b/source/blender/editors/interface/interface_region_popover.cc index 2e10261a4f7..17c8d890755 100644 --- a/source/blender/editors/interface/interface_region_popover.cc +++ b/source/blender/editors/interface/interface_region_popover.cc @@ -46,7 +46,7 @@ #include "UI_interface.h" #include "interface_intern.h" -#include "interface_regions_intern.h" +#include "interface_regions_intern.hh" /* -------------------------------------------------------------------- */ /** \name Popup Menu with Callback or String @@ -397,7 +397,7 @@ void UI_popover_end(bContext *C, uiPopover *pup, wmKeyMap *keymap) pup->window = window; - /* TODO(campbell): we may want to make this configurable. + /* TODO(@campbellbarton): we may want to make this configurable. * The begin/end stype of calling popups doesn't allow 'can_refresh' to be set. * For now close this style of popovers when accessed. */ UI_block_flag_disable(pup->block, UI_BLOCK_KEEP_OPEN); diff --git a/source/blender/editors/interface/interface_region_popup.cc b/source/blender/editors/interface/interface_region_popup.cc index 74c228e3338..f6b078c033e 100644 --- a/source/blender/editors/interface/interface_region_popup.cc +++ b/source/blender/editors/interface/interface_region_popup.cc @@ -31,7 +31,7 @@ #include "ED_screen.h" #include "interface_intern.h" -#include "interface_regions_intern.h" +#include "interface_regions_intern.hh" /* -------------------------------------------------------------------- */ /** \name Utility Functions diff --git a/source/blender/editors/interface/interface_region_search.cc b/source/blender/editors/interface/interface_region_search.cc index 81c0c29d09a..6bb47666afd 100644 --- a/source/blender/editors/interface/interface_region_search.cc +++ b/source/blender/editors/interface/interface_region_search.cc @@ -41,7 +41,7 @@ #include "GPU_state.h" #include "interface_intern.h" -#include "interface_regions_intern.h" +#include "interface_regions_intern.hh" #define MENU_BORDER (int)(0.3f * U.widget_unit) @@ -710,18 +710,18 @@ static ARegion *ui_searchbox_create_generic_ex(bContext *C, type.regionid = RGN_TYPE_TEMPORARY; region->type = &type; - /* create searchbox data */ + /* Create search-box data. */ uiSearchboxData *data = MEM_cnew<uiSearchboxData>(__func__); - /* set font, get bb */ + /* Set font, get the bounding-box. */ data->fstyle = style->widget; /* copy struct */ ui_fontscale(&data->fstyle.points, aspect); UI_fontstyle_set(&data->fstyle); region->regiondata = data; - /* special case, hardcoded feature, not draw backdrop when called from menus, - * assume for design that popup already added it */ + /* Special case, hard-coded feature, not draw backdrop when called from menus, + * assume for design that popup already added it. */ if (but->block->flag & UI_BLOCK_SEARCH_MENU) { data->noback = true; } diff --git a/source/blender/editors/interface/interface_region_tooltip.c b/source/blender/editors/interface/interface_region_tooltip.cc index f460a159a5f..8d88261c328 100644 --- a/source/blender/editors/interface/interface_region_tooltip.c +++ b/source/blender/editors/interface/interface_region_tooltip.cc @@ -7,7 +7,7 @@ * ToolTip Region and Construction */ -/* TODO(campbell): +/* TODO(@campbellbarton): * We may want to have a higher level API that initializes a timer, * checks for mouse motion and clears the tool-tip afterwards. * We never want multiple tool-tips at once @@ -16,9 +16,9 @@ * For now it's not a priority, so leave as-is. */ -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> +#include <cstdarg> +#include <cstdlib> +#include <cstring> #include "MEM_guardedalloc.h" @@ -53,7 +53,7 @@ #include "ED_screen.h" #include "interface_intern.h" -#include "interface_regions_intern.h" +#include "interface_regions_intern.hh" #define UI_TIP_PAD_FAC 1.3f #define UI_TIP_PADDING (int)(UI_TIP_PAD_FAC * UI_UNIT_Y) @@ -61,59 +61,82 @@ #define UI_TIP_STR_MAX 1024 -typedef struct uiTooltipFormat { - enum { - UI_TIP_STYLE_NORMAL = 0, - UI_TIP_STYLE_HEADER, - UI_TIP_STYLE_MONO, - } style : 3; - enum { - UI_TIP_LC_MAIN = 0, /* primary text */ - UI_TIP_LC_VALUE, /* the value of buttons (also shortcuts) */ - UI_TIP_LC_ACTIVE, /* titles of active enum values */ - UI_TIP_LC_NORMAL, /* regular text */ - UI_TIP_LC_PYTHON, /* Python snippet */ - UI_TIP_LC_ALERT, /* description of why operator can't run */ - } color_id : 4; - int is_pad : 1; -} uiTooltipFormat; - -typedef struct uiTooltipField { +struct uiTooltipFormat { + enum class Style : int8_t { + Normal, + Header, + Mono, + }; + enum class ColorID : int8_t { + /** Primary Text. */ + Main = 0, + /** The value of buttons (also shortcuts). */ + Value = 1, + /** Titles of active enum values. */ + Active = 2, + /** Regular text. */ + Normal = 3, + /** Python snippet. */ + Python = 4, + /** Description of why an operator can't run. */ + Alert = 5, + }; + Style style; + ColorID color_id; + bool is_pad; +}; + +struct uiTooltipField { char *text; char *text_suffix; struct { - uint x_pos; /* x cursor position at the end of the last line */ - uint lines; /* number of lines, 1 or more with word-wrap */ + /** X cursor position at the end of the last line. */ + uint x_pos; + /** Number of lines, 1 or more with word-wrap. */ + uint lines; } geom; uiTooltipFormat format; +}; -} uiTooltipField; - -typedef struct uiTooltipData { +struct uiTooltipData { rcti bbox; uiTooltipField *fields; uint fields_len; uiFontStyle fstyle; int wrap_width; int toth, lineh; -} uiTooltipData; +}; #define UI_TIP_LC_MAX 6 -BLI_STATIC_ASSERT(UI_TIP_LC_MAX == UI_TIP_LC_ALERT + 1, "invalid lc-max"); +BLI_STATIC_ASSERT(UI_TIP_LC_MAX == static_cast<int>(uiTooltipFormat::ColorID::Alert) + 1, + "invalid lc-max"); BLI_STATIC_ASSERT(sizeof(uiTooltipFormat) <= sizeof(int), "oversize"); static uiTooltipField *text_field_add_only(uiTooltipData *data) { data->fields_len += 1; - data->fields = MEM_recallocN(data->fields, sizeof(*data->fields) * data->fields_len); + data->fields = static_cast<uiTooltipField *>( + MEM_recallocN(data->fields, sizeof(*data->fields) * data->fields_len)); return &data->fields[data->fields_len - 1]; } -static uiTooltipField *text_field_add(uiTooltipData *data, const uiTooltipFormat *format) +// static uiTooltipField *text_field_add(uiTooltipData *data, const uiTooltipFormat *format) +// { +// uiTooltipField *field = text_field_add_only(data); +// field->format = *format; +// return field; +// } + +static uiTooltipField *text_field_add(uiTooltipData *data, + const uiTooltipFormat::Style style, + const uiTooltipFormat::ColorID color, + const bool is_pad = false) { uiTooltipField *field = text_field_add_only(data); - field->format = *format; + field->format = {}; + field->format.style = style; + field->format.color_id = color, field->format.is_pad = is_pad; return field; } @@ -138,30 +161,31 @@ static void rgb_tint(float col[3], float h, float h_strength, float v, float v_s static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region) { const float pad_px = UI_TIP_PADDING; - uiTooltipData *data = region->regiondata; + uiTooltipData *data = static_cast<uiTooltipData *>(region->regiondata); const uiWidgetColors *theme = ui_tooltip_get_theme(); rcti bbox = data->bbox; float tip_colors[UI_TIP_LC_MAX][3]; uchar drawcol[4] = {0, 0, 0, 255}; /* to store color in while drawing (alpha is always 255) */ - float *main_color = tip_colors[UI_TIP_LC_MAIN]; /* the color from the theme */ - float *value_color = tip_colors[UI_TIP_LC_VALUE]; - float *active_color = tip_colors[UI_TIP_LC_ACTIVE]; - float *normal_color = tip_colors[UI_TIP_LC_NORMAL]; - float *python_color = tip_colors[UI_TIP_LC_PYTHON]; - float *alert_color = tip_colors[UI_TIP_LC_ALERT]; + /* The color from the theme. */ + float *main_color = tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Main)]; + float *value_color = tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Value)]; + float *active_color = tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Active)]; + float *normal_color = tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Normal)]; + float *python_color = tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Python)]; + float *alert_color = tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Alert)]; float background_color[3]; wmOrtho2_region_pixelspace(region); - /* draw background */ - ui_draw_tooltip_background(UI_style_get(), NULL, &bbox); + /* Draw background. */ + ui_draw_tooltip_background(UI_style_get(), nullptr, &bbox); /* set background_color */ rgb_uchar_to_float(background_color, theme->inner); - /* calculate normal_color */ + /* Calculate `normal_color`. */ rgb_uchar_to_float(main_color, theme->text); copy_v3_v3(active_color, main_color); copy_v3_v3(normal_color, main_color); @@ -169,19 +193,19 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region copy_v3_v3(alert_color, main_color); copy_v3_v3(value_color, main_color); - /* find the brightness difference between background and text colors */ + /* Find the brightness difference between background and text colors. */ const float tone_bg = rgb_to_grayscale(background_color); - /* tone_fg = rgb_to_grayscale(main_color); */ + // tone_fg = rgb_to_grayscale(main_color); - /* mix the colors */ + /* Mix the colors. */ rgb_tint(value_color, 0.0f, 0.0f, tone_bg, 0.2f); /* Light gray. */ rgb_tint(active_color, 0.6f, 0.2f, tone_bg, 0.2f); /* Light blue. */ rgb_tint(normal_color, 0.0f, 0.0f, tone_bg, 0.4f); /* Gray. */ rgb_tint(python_color, 0.0f, 0.0f, tone_bg, 0.5f); /* Dark gray. */ rgb_tint(alert_color, 0.0f, 0.8f, tone_bg, 0.1f); /* Red. */ - /* draw text */ + /* Draw text. */ BLF_wordwrap(data->fstyle.uifont_id, data->wrap_width); BLF_wordwrap(blf_mono_font, data->wrap_width); @@ -190,58 +214,58 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region for (int i = 0; i < data->fields_len; i++) { const uiTooltipField *field = &data->fields[i]; - const uiTooltipField *field_next = (i + 1) != data->fields_len ? &data->fields[i + 1] : NULL; + const uiTooltipField *field_next = (i + 1) != data->fields_len ? &data->fields[i + 1] : + nullptr; bbox.ymin = bbox.ymax - (data->lineh * field->geom.lines); - if (field->format.style == UI_TIP_STYLE_HEADER) { - const struct uiFontStyleDraw_Params fs_params = { - .align = UI_STYLE_TEXT_LEFT, - .word_wrap = true, - }; - /* draw header and active data (is done here to be able to change color) */ - rgb_float_to_uchar(drawcol, tip_colors[UI_TIP_LC_MAIN]); + if (field->format.style == uiTooltipFormat::Style::Header) { + uiFontStyleDraw_Params fs_params{}; + fs_params.align = UI_STYLE_TEXT_LEFT; + fs_params.word_wrap = true; + + /* Draw header and active data (is done here to be able to change color). */ + rgb_float_to_uchar(drawcol, tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Main)]); UI_fontstyle_set(&data->fstyle); UI_fontstyle_draw(&data->fstyle, &bbox, field->text, UI_TIP_STR_MAX, drawcol, &fs_params); - /* offset to the end of the last line */ + /* Offset to the end of the last line. */ if (field->text_suffix) { const float xofs = field->geom.x_pos; const float yofs = data->lineh * (field->geom.lines - 1); bbox.xmin += xofs; bbox.ymax -= yofs; - rgb_float_to_uchar(drawcol, tip_colors[UI_TIP_LC_ACTIVE]); + rgb_float_to_uchar(drawcol, + tip_colors[static_cast<int>(uiTooltipFormat::ColorID::Active)]); UI_fontstyle_draw( &data->fstyle, &bbox, field->text_suffix, UI_TIP_STR_MAX, drawcol, &fs_params); - /* undo offset */ + /* Undo offset. */ bbox.xmin -= xofs; bbox.ymax += yofs; } } - else if (field->format.style == UI_TIP_STYLE_MONO) { - const struct uiFontStyleDraw_Params fs_params = { - .align = UI_STYLE_TEXT_LEFT, - .word_wrap = true, - }; + else if (field->format.style == uiTooltipFormat::Style::Mono) { + uiFontStyleDraw_Params fs_params{}; + fs_params.align = UI_STYLE_TEXT_LEFT; + fs_params.word_wrap = true; uiFontStyle fstyle_mono = data->fstyle; fstyle_mono.uifont_id = blf_mono_font; UI_fontstyle_set(&fstyle_mono); - /* XXX, needed because we don't have mono in 'U.uifonts' */ + /* XXX: needed because we don't have mono in 'U.uifonts'. */ BLF_size(fstyle_mono.uifont_id, fstyle_mono.points * U.pixelsize, U.dpi); - rgb_float_to_uchar(drawcol, tip_colors[field->format.color_id]); + rgb_float_to_uchar(drawcol, tip_colors[static_cast<int>(field->format.color_id)]); UI_fontstyle_draw(&fstyle_mono, &bbox, field->text, UI_TIP_STR_MAX, drawcol, &fs_params); } else { - BLI_assert(field->format.style == UI_TIP_STYLE_NORMAL); - const struct uiFontStyleDraw_Params fs_params = { - .align = UI_STYLE_TEXT_LEFT, - .word_wrap = true, - }; - - /* draw remaining data */ - rgb_float_to_uchar(drawcol, tip_colors[field->format.color_id]); + BLI_assert(field->format.style == uiTooltipFormat::Style::Normal); + uiFontStyleDraw_Params fs_params{}; + fs_params.align = UI_STYLE_TEXT_LEFT; + fs_params.word_wrap = true; + + /* Draw remaining data. */ + rgb_float_to_uchar(drawcol, tip_colors[static_cast<int>(field->format.color_id)]); UI_fontstyle_set(&data->fstyle); UI_fontstyle_draw(&data->fstyle, &bbox, field->text, UI_TIP_STR_MAX, drawcol, &fs_params); } @@ -259,7 +283,7 @@ static void ui_tooltip_region_draw_cb(const bContext *UNUSED(C), ARegion *region static void ui_tooltip_region_free_cb(ARegion *region) { - uiTooltipData *data = region->regiondata; + uiTooltipData *data = static_cast<uiTooltipData *>(region->regiondata); for (int i = 0; i < data->fields_len; i++) { const uiTooltipField *field = &data->fields[i]; @@ -270,7 +294,7 @@ static void ui_tooltip_region_free_cb(ARegion *region) } MEM_freeN(data->fields); MEM_freeN(data); - region->regiondata = NULL; + region->regiondata = nullptr; } /** \} */ @@ -281,7 +305,7 @@ static void ui_tooltip_region_free_cb(ARegion *region) static char *ui_tooltip_text_python_from_op(bContext *C, wmOperatorType *ot, PointerRNA *opptr) { - char *str = WM_operator_pystring_ex(C, NULL, false, false, ot, opptr); + char *str = WM_operator_pystring_ex(C, nullptr, false, false, ot, opptr); /* Avoid overly verbose tips (eg, arrays of 20 layers), exact limit is arbitrary. */ WM_operator_pystring_abbreviate(str, 32); @@ -304,24 +328,17 @@ static bool ui_tooltip_data_append_from_keymap(bContext *C, uiTooltipData *data, LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) { wmOperatorType *ot = WM_operatortype_find(kmi->idname, true); - if (ot != NULL) { - /* Tip */ + if (ot != nullptr) { + /* Tip. */ { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_MAIN, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Main, true); field->text = BLI_strdup(ot->description ? ot->description : ot->name); } - /* Shortcut */ + /* Shortcut. */ { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_NORMAL, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Normal); bool found = false; if (WM_keymap_item_to_string(kmi, false, buf, sizeof(buf))) { found = true; @@ -329,13 +346,10 @@ static bool ui_tooltip_data_append_from_keymap(bContext *C, uiTooltipData *data, field->text = BLI_sprintfN(TIP_("Shortcut: %s"), found ? buf : "None"); } - /* Python */ + /* Python. */ if (U.flag & USER_TOOLTIPS_PYTHON) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_PYTHON, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Python); char *str = ui_tooltip_text_python_from_op(C, ot, kmi->ptr); field->text = BLI_sprintfN(TIP_("Python: %s"), str); MEM_freeN(str); @@ -353,17 +367,17 @@ static bool ui_tooltip_data_append_from_keymap(bContext *C, uiTooltipData *data, */ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is_label) { - if (but->optype == NULL) { - return NULL; + if (but->optype == nullptr) { + return nullptr; } if (!STREQ(but->optype->idname, "WM_OT_tool_set_by_id")) { - return NULL; + return nullptr; } /* Needed to get the space-data's type (below). */ - if (CTX_wm_space_data(C) == NULL) { - return NULL; + if (CTX_wm_space_data(C) == nullptr) { + return nullptr; } char tool_id[MAX_NAME]; @@ -378,7 +392,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is const char *has_valid_context_error = IFACE_("Unsupported context"); { ScrArea *area = CTX_wm_area(C); - if (area == NULL) { + if (area == nullptr) { has_valid_context = false; } else { @@ -393,16 +407,15 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is } /* We have a tool, now extract the info. */ - uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData"); + uiTooltipData *data = MEM_cnew<uiTooltipData>(__func__); #ifdef WITH_PYTHON - /* it turns out to be most simple to do this via Python since C - * doesn't have access to information about non-active tools. - */ + /* It turns out to be most simple to do this via Python since C + * doesn't have access to information about non-active tools. */ /* Title (when icon-only). */ if (but->drawstr[0] == '\0') { - const char *expr_imports[] = {"bpy", "bl_ui", NULL}; + const char *expr_imports[] = {"bpy", "bl_ui", nullptr}; char expr[256]; SNPRINTF(expr, "bl_ui.space_toolsystem_common.item_from_id(" @@ -410,16 +423,16 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is "bpy.context.space_data.type, " "'%s').label", tool_id); - char *expr_result = NULL; + char *expr_result = nullptr; bool is_error = false; if (has_valid_context == false) { expr_result = BLI_strdup(has_valid_context_error); } - else if (BPY_run_string_as_string(C, expr_imports, expr, NULL, &expr_result)) { + else if (BPY_run_string_as_string(C, expr_imports, expr, nullptr, &expr_result)) { if (STREQ(expr_result, "")) { MEM_freeN(expr_result); - expr_result = NULL; + expr_result = nullptr; } } else { @@ -429,7 +442,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is is_error = true; } - if (expr_result != NULL) { + if (expr_result != nullptr) { /* NOTE: This is a very weak hack to get a valid translation most of the time... * Proper way to do would be to get i18n context from the item, somehow. */ const char *label_str = CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, expr_result); @@ -442,23 +455,19 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is expr_result = BLI_strdup(label_str); } - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_MAIN, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Main, true); field->text = expr_result; if (UNLIKELY(is_error)) { - field->format.color_id = UI_TIP_LC_ALERT; + field->format.color_id = uiTooltipFormat::ColorID::Alert; } } } /* Tip. */ if (is_label == false) { - const char *expr_imports[] = {"bpy", "bl_ui", NULL}; + const char *expr_imports[] = {"bpy", "bl_ui", nullptr}; char expr[256]; SNPRINTF(expr, "bl_ui.space_toolsystem_common.description_from_id(" @@ -467,16 +476,16 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is "'%s') + '.'", tool_id); - char *expr_result = NULL; + char *expr_result = nullptr; bool is_error = false; if (has_valid_context == false) { expr_result = BLI_strdup(has_valid_context_error); } - else if (BPY_run_string_as_string(C, expr_imports, expr, NULL, &expr_result)) { + else if (BPY_run_string_as_string(C, expr_imports, expr, nullptr, &expr_result)) { if (STREQ(expr_result, ".")) { MEM_freeN(expr_result); - expr_result = NULL; + expr_result = nullptr; } } else { @@ -486,17 +495,13 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is is_error = true; } - if (expr_result != NULL) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_MAIN, - .is_pad = true, - }); + if (expr_result != nullptr) { + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Main, true); field->text = expr_result; if (UNLIKELY(is_error)) { - field->format.color_id = UI_TIP_LC_ALERT; + field->format.color_id = uiTooltipFormat::ColorID::Alert; } } } @@ -515,18 +520,18 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is * * Either way case it's useful to show the shortcut. */ - char *shortcut = NULL; + char *shortcut = nullptr; { - uiStringInfo op_keymap = {BUT_GET_OP_KEYMAP, NULL}; - UI_but_string_info_get(C, but, &op_keymap, NULL); + uiStringInfo op_keymap = {BUT_GET_OP_KEYMAP, nullptr}; + UI_but_string_info_get(C, but, &op_keymap, nullptr); shortcut = op_keymap.strinfo; } - if (shortcut == NULL) { + if (shortcut == nullptr) { const ePaintMode paint_mode = BKE_paintmode_get_active_from_context(C); const char *tool_attr = BKE_paint_get_tool_prop_id_from_paintmode(paint_mode); - if (tool_attr != NULL) { + if (tool_attr != nullptr) { const EnumPropertyItem *items = BKE_paint_get_tool_enum_from_paintmode(paint_mode); const char *tool_id_lstrip = strrchr(tool_id, '.'); const int tool_id_offset = tool_id_lstrip ? ((tool_id_lstrip - tool_id) + 1) : 0; @@ -543,7 +548,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is if (WM_key_event_operator_string(C, ot->idname, WM_OP_INVOKE_REGION_WIN, - op_props.data, + static_cast<IDProperty *>(op_props.data), true, shortcut_brush, ARRAY_SIZE(shortcut_brush))) { @@ -554,20 +559,20 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is } } - if (shortcut == NULL) { + if (shortcut == nullptr) { /* Check for direct access to the tool. */ char shortcut_toolbar[128] = ""; if (WM_key_event_operator_string(C, "WM_OT_toolbar", WM_OP_INVOKE_REGION_WIN, - NULL, + nullptr, true, shortcut_toolbar, ARRAY_SIZE(shortcut_toolbar))) { /* Generate keymap in order to inspect it. * NOTE: we could make a utility to avoid the keymap generation part of this. */ const char *expr_imports[] = { - "bpy", "bl_keymap_utils", "bl_keymap_utils.keymap_from_toolbar", NULL}; + "bpy", "bl_keymap_utils", "bl_keymap_utils.keymap_from_toolbar", nullptr}; const char *expr = ("getattr(" "bl_keymap_utils.keymap_from_toolbar.generate(" @@ -580,7 +585,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is if (has_valid_context == false) { shortcut = BLI_strdup(has_valid_context_error); } - else if (BPY_run_string_as_intptr(C, expr_imports, expr, NULL, &expr_result)) { + else if (BPY_run_string_as_intptr(C, expr_imports, expr, nullptr, &expr_result)) { if (expr_result != 0) { wmKeyMap *keymap = (wmKeyMap *)expr_result; LISTBASE_FOREACH (wmKeyMapItem *, kmi, &keymap->items) { @@ -603,13 +608,9 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is } } - if (shortcut != NULL) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_VALUE, - .is_pad = true, - }); + if (shortcut != nullptr) { + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true); field->text = BLI_sprintfN(TIP_("Shortcut: %s"), shortcut); MEM_freeN(shortcut); } @@ -627,11 +628,11 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is * This is a little involved since the shortcut may be bound to another tool in this group, * instead of the current tool on display. */ - char *expr_result = NULL; + char *expr_result = nullptr; size_t expr_result_len; { - const char *expr_imports[] = {"bpy", "bl_ui", NULL}; + const char *expr_imports[] = {"bpy", "bl_ui", nullptr}; char expr[256]; SNPRINTF(expr, "'\\x00'.join(" @@ -645,12 +646,12 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is /* pass */ } else if (BPY_run_string_as_string_and_size( - C, expr_imports, expr, NULL, &expr_result, &expr_result_len)) { + C, expr_imports, expr, nullptr, &expr_result, &expr_result_len)) { /* pass. */ } } - if (expr_result != NULL) { + if (expr_result != nullptr) { PointerRNA op_props; WM_operator_properties_create_ptr(&op_props, but->optype); RNA_boolean_set(&op_props, "cycle", true); @@ -665,7 +666,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is if (WM_key_event_operator_string(C, but->optype->idname, WM_OP_INVOKE_REGION_WIN, - op_props.data, + static_cast<IDProperty *>(op_props.data), true, shortcut, ARRAY_SIZE(shortcut))) { @@ -678,12 +679,8 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is MEM_freeN(expr_result); if (shortcut[0] != '\0') { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_VALUE, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true); field->text = BLI_sprintfN(TIP_("Shortcut Cycle: %s"), shortcut); } } @@ -691,12 +688,8 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is /* Python */ if ((is_label == false) && (U.flag & USER_TOOLTIPS_PYTHON)) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_PYTHON, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Python, true); char *str = ui_tooltip_text_python_from_op(C, but->optype, but->opptr); field->text = BLI_sprintfN(TIP_("Python: %s"), str); MEM_freeN(str); @@ -706,7 +699,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is /* This is too handy not to expose somehow, let's be sneaky for now. */ if ((is_label == false) && CTX_wm_window(C)->eventstate->modifier & KM_SHIFT) { - const char *expr_imports[] = {"bpy", "bl_ui", NULL}; + const char *expr_imports[] = {"bpy", "bl_ui", nullptr}; char expr[256]; SNPRINTF(expr, "getattr(" @@ -722,15 +715,11 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is if (has_valid_context == false) { /* pass */ } - else if (BPY_run_string_as_intptr(C, expr_imports, expr, NULL, &expr_result)) { + else if (BPY_run_string_as_intptr(C, expr_imports, expr, nullptr, &expr_result)) { if (expr_result != 0) { { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_NORMAL, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Normal, true); field->text = BLI_strdup("Tool Keymap:"); } wmKeyMap *keymap = (wmKeyMap *)expr_result; @@ -747,7 +736,7 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is if (data->fields_len == 0) { MEM_freeN(data); - return NULL; + return nullptr; } return data; } @@ -756,26 +745,26 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, uiBut *but, uiButExtraOpIcon *extra_icon) { - uiStringInfo but_label = {BUT_GET_LABEL, NULL}; - uiStringInfo but_tip = {BUT_GET_TIP, NULL}; - uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, NULL}; - uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, NULL}; - uiStringInfo op_keymap = {BUT_GET_OP_KEYMAP, NULL}; - uiStringInfo prop_keymap = {BUT_GET_PROP_KEYMAP, NULL}; - uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, NULL}; - uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, NULL}; + uiStringInfo but_label = {BUT_GET_LABEL, nullptr}; + uiStringInfo but_tip = {BUT_GET_TIP, nullptr}; + uiStringInfo enum_label = {BUT_GET_RNAENUM_LABEL, nullptr}; + uiStringInfo enum_tip = {BUT_GET_RNAENUM_TIP, nullptr}; + uiStringInfo op_keymap = {BUT_GET_OP_KEYMAP, nullptr}; + uiStringInfo prop_keymap = {BUT_GET_PROP_KEYMAP, nullptr}; + uiStringInfo rna_struct = {BUT_GET_RNASTRUCT_IDENTIFIER, nullptr}; + uiStringInfo rna_prop = {BUT_GET_RNAPROP_IDENTIFIER, nullptr}; char buf[512]; wmOperatorType *optype = extra_icon ? UI_but_extra_operator_icon_optype_get(extra_icon) : but->optype; - PropertyRNA *rnaprop = extra_icon ? NULL : but->rnaprop; + PropertyRNA *rnaprop = extra_icon ? nullptr : but->rnaprop; /* create tooltip data */ - uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData"); + uiTooltipData *data = MEM_cnew<uiTooltipData>(__func__); if (extra_icon) { - UI_but_extra_icon_string_info_get(C, extra_icon, &but_label, &but_tip, &op_keymap, NULL); + UI_but_extra_icon_string_info_get(C, extra_icon, &but_label, &but_tip, &op_keymap, nullptr); } else { UI_but_string_info_get(C, @@ -788,30 +777,25 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, &prop_keymap, &rna_struct, &rna_prop, - NULL); + nullptr); } /* Tip Label (only for buttons not already showing the label). * Check prefix instead of comparing because the button may include the shortcut. - * Buttons with dynamic tooltips also don't get their default label here since they - * can already provide more accurate and specific tooltip content. */ + * Buttons with dynamic tool-tips also don't get their default label here since they + * can already provide more accurate and specific tool-tip content. */ if (but_label.strinfo && !STRPREFIX(but->drawstr, but_label.strinfo) && !but->tip_func) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_HEADER, - .color_id = UI_TIP_LC_NORMAL, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Header, uiTooltipFormat::ColorID::Normal); + field->text = BLI_strdup(but_label.strinfo); } /* Tip */ if (but_tip.strinfo) { { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_HEADER, - .color_id = UI_TIP_LC_NORMAL, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Header, uiTooltipFormat::ColorID::Normal); if (enum_label.strinfo) { field->text = BLI_sprintfN("%s: ", but_tip.strinfo); field->text_suffix = BLI_strdup(enum_label.strinfo); @@ -823,59 +807,40 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, /* special case enum rna buttons */ if ((but->type & UI_BTYPE_ROW) && rnaprop && RNA_property_flag(rnaprop) & PROP_ENUM_FLAG) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_NORMAL, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Normal); field->text = BLI_strdup(TIP_("(Shift-Click/Drag to select multiple)")); } } - /* Enum field label & tip */ + /* Enum field label & tip. */ if (enum_tip.strinfo) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_VALUE, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value); field->text = BLI_strdup(enum_tip.strinfo); } - /* Op shortcut */ + /* Operator shortcut. */ if (op_keymap.strinfo) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_VALUE, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true); field->text = BLI_sprintfN(TIP_("Shortcut: %s"), op_keymap.strinfo); } - /* Property context-toggle shortcut */ + /* Property context-toggle shortcut. */ if (prop_keymap.strinfo) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_VALUE, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true); field->text = BLI_sprintfN(TIP_("Shortcut: %s"), prop_keymap.strinfo); } if (ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) { - /* better not show the value of a password */ + /* Better not show the value of a password. */ if ((rnaprop && (RNA_property_subtype(rnaprop) == PROP_PASSWORD)) == 0) { - /* full string */ + /* Full string. */ ui_but_string_get(but, buf, sizeof(buf)); if (buf[0]) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_VALUE, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true); field->text = BLI_sprintfN(TIP_("Value: %s"), buf); } } @@ -890,22 +855,16 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, RNA_property_float_get_index(&but->rnapoin, rnaprop, but->rnaindex) : RNA_property_float_get(&but->rnapoin, rnaprop); - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_VALUE, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value); field->text = BLI_sprintfN(TIP_("Radians: %f"), value); } } if (but->flag & UI_BUT_DRIVEN) { if (ui_but_anim_expression_get(but, buf, sizeof(buf))) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_NORMAL, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Normal); field->text = BLI_sprintfN(TIP_("Expression: %s"), buf); } } @@ -913,64 +872,56 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, if (but->rnapoin.owner_id) { const ID *id = but->rnapoin.owner_id; if (ID_IS_LINKED(id)) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_NORMAL, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Normal); field->text = BLI_sprintfN(TIP_("Library: %s"), id->lib->filepath); } } } else if (optype) { PointerRNA *opptr = extra_icon ? UI_but_extra_operator_icon_opptr_get(extra_icon) : - /* allocated when needed, the button owns it */ + /* Allocated when needed, the button owns it. */ UI_but_operator_ptr_get(but); - /* so the context is passed to fieldf functions (some py fieldf functions use it) */ + /* So the context is passed to field functions (some Python field functions use it). */ WM_operator_properties_sanitize(opptr, false); char *str = ui_tooltip_text_python_from_op(C, optype, opptr); - /* operator info */ + /* Operator info. */ if (U.flag & USER_TOOLTIPS_PYTHON) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_MONO, - .color_id = UI_TIP_LC_PYTHON, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Mono, uiTooltipFormat::ColorID::Python, true); field->text = BLI_sprintfN(TIP_("Python: %s"), str); } MEM_freeN(str); } - /* button is disabled, we may be able to tell user why */ + /* Button is disabled, we may be able to tell user why. */ if ((but->flag & UI_BUT_DISABLED) || extra_icon) { - const char *disabled_msg = NULL; + const char *disabled_msg = nullptr; bool disabled_msg_free = false; - /* if operator poll check failed, it can give pretty precise info why */ + /* If operator poll check failed, it can give pretty precise info why. */ if (optype) { const wmOperatorCallContext opcontext = extra_icon ? extra_icon->optype_params->opcontext : but->opcontext; + wmOperatorCallParams call_params{}; + call_params.optype = optype; + call_params.opcontext = opcontext; CTX_wm_operator_poll_msg_clear(C); - ui_but_context_poll_operator_ex( - C, but, &(wmOperatorCallParams){.optype = optype, .opcontext = opcontext}); + ui_but_context_poll_operator_ex(C, but, &call_params); disabled_msg = CTX_wm_operator_poll_msg_get(C, &disabled_msg_free); } - /* alternatively, buttons can store some reasoning too */ + /* Alternatively, buttons can store some reasoning too. */ else if (!extra_icon && but->disabled_info) { disabled_msg = TIP_(but->disabled_info); } if (disabled_msg && disabled_msg[0]) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_ALERT, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Alert); field->text = BLI_sprintfN(TIP_("Disabled: %s"), disabled_msg); } if (disabled_msg_free) { @@ -980,30 +931,23 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, if ((U.flag & USER_TOOLTIPS_PYTHON) && !optype && rna_struct.strinfo) { { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_MONO, - .color_id = UI_TIP_LC_PYTHON, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Mono, uiTooltipFormat::ColorID::Python, true); if (rna_prop.strinfo) { /* Struct and prop */ field->text = BLI_sprintfN(TIP_("Python: %s.%s"), rna_struct.strinfo, rna_prop.strinfo); } else { - /* Only struct (e.g. menus) */ + /* Only struct (e.g. menus). */ field->text = BLI_sprintfN(TIP_("Python: %s"), rna_struct.strinfo); } } if (but->rnapoin.owner_id) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_MONO, - .color_id = UI_TIP_LC_PYTHON, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Mono, uiTooltipFormat::ColorID::Python); - /* this could get its own 'BUT_GET_...' type */ + /* This could get its own `BUT_GET_...` type. */ /* never fails */ /* Move ownership (no need for re-allocation). */ @@ -1045,73 +989,66 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, if (data->fields_len == 0) { MEM_freeN(data); - return NULL; + return nullptr; } return data; } static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz) { - uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData"); + uiTooltipData *data = MEM_cnew<uiTooltipData>(__func__); - /* TODO(campbell): a way for gizmos to have their own descriptions (low priority). */ + /* TODO(@campbellbarton): a way for gizmos to have their own descriptions (low priority). */ /* Operator Actions */ { const bool use_drag = gz->drag_part != -1 && gz->highlight_part != gz->drag_part; - const struct { + struct GizmoOpActions { int part; const char *prefix; - } gzop_actions[] = { + }; + GizmoOpActions gzop_actions[] = { { - .part = gz->highlight_part, - .prefix = use_drag ? CTX_TIP_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Click") : NULL, + gz->highlight_part, + use_drag ? CTX_TIP_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Click") : nullptr, }, { - .part = use_drag ? gz->drag_part : -1, - .prefix = use_drag ? CTX_TIP_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Drag") : NULL, + use_drag ? gz->drag_part : -1, + use_drag ? CTX_TIP_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Drag") : nullptr, }, }; for (int i = 0; i < ARRAY_SIZE(gzop_actions); i++) { wmGizmoOpElem *gzop = (gzop_actions[i].part != -1) ? WM_gizmo_operator_get(gz, gzop_actions[i].part) : - NULL; - if (gzop != NULL) { + nullptr; + if (gzop != nullptr) { /* Description */ char *info = WM_operatortype_description_or_name(C, gzop->type, &gzop->ptr); - if (info != NULL) { + if (info != nullptr) { char *text = info; - if (gzop_actions[i].prefix != NULL) { + if (gzop_actions[i].prefix != nullptr) { text = BLI_sprintfN("%s: %s", gzop_actions[i].prefix, info); MEM_freeN(info); } - if (text != NULL) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_HEADER, - .color_id = UI_TIP_LC_VALUE, - .is_pad = true, - }); + if (text != nullptr) { + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Header, uiTooltipFormat::ColorID::Value, true); field->text = text; } } /* Shortcut */ { - IDProperty *prop = gzop->ptr.data; + IDProperty *prop = static_cast<IDProperty *>(gzop->ptr.data); char buf[128]; if (WM_key_event_operator_string( C, gzop->type->idname, WM_OP_INVOKE_DEFAULT, prop, true, buf, ARRAY_SIZE(buf))) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_VALUE, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true); field->text = BLI_sprintfN(TIP_("Shortcut: %s"), buf); } } @@ -1123,17 +1060,13 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz) if (gz->type->target_property_defs_len) { wmGizmoProperty *gz_prop_array = WM_gizmo_target_property_array(gz); for (int i = 0; i < gz->type->target_property_defs_len; i++) { - /* TODO(campbell): function callback descriptions. */ + /* TODO(@campbellbarton): function callback descriptions. */ wmGizmoProperty *gz_prop = &gz_prop_array[i]; - if (gz_prop->prop != NULL) { + if (gz_prop->prop != nullptr) { const char *info = RNA_property_ui_description(gz_prop->prop); if (info && info[0]) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_VALUE, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true); field->text = BLI_strdup(info); } } @@ -1142,7 +1075,7 @@ static uiTooltipData *ui_tooltip_data_from_gizmo(bContext *C, wmGizmo *gz) if (data->fields_len == 0) { MEM_freeN(data); - return NULL; + return nullptr; } return data; } @@ -1161,7 +1094,7 @@ static ARegion *ui_tooltip_create_with_data(bContext *C, rcti rect_i; int font_flag = 0; - /* create area region */ + /* Create area region. */ ARegion *region = ui_region_temp_add(CTX_wm_screen(C)); static ARegionType type; @@ -1171,7 +1104,7 @@ static ARegion *ui_tooltip_create_with_data(bContext *C, type.regionid = RGN_TYPE_TEMPORARY; region->type = &type; - /* set font, get bb */ + /* Set font, get bounding-box. */ data->fstyle = style->widget; /* copy struct */ ui_fontscale(&data->fstyle.points, aspect); @@ -1185,7 +1118,7 @@ static ARegion *ui_tooltip_create_with_data(bContext *C, BLF_wordwrap(data->fstyle.uifont_id, data->wrap_width); BLF_wordwrap(blf_mono_font, data->wrap_width); - /* these defines tweaked depending on font */ + /* These defines tweaked depending on font. */ #define TIP_BORDER_X (16.0f / aspect) #define TIP_BORDER_Y (6.0f / aspect) @@ -1194,18 +1127,19 @@ static ARegion *ui_tooltip_create_with_data(bContext *C, int i, fonth, fontw; for (i = 0, fontw = 0, fonth = 0; i < data->fields_len; i++) { uiTooltipField *field = &data->fields[i]; - uiTooltipField *field_next = (i + 1) != data->fields_len ? &data->fields[i + 1] : NULL; + uiTooltipField *field_next = (i + 1) != data->fields_len ? &data->fields[i + 1] : nullptr; struct ResultBLF info; int w, x_pos = 0; int font_id; - if (field->format.style == UI_TIP_STYLE_MONO) { + if (field->format.style == uiTooltipFormat::Style::Mono) { BLF_size(blf_mono_font, data->fstyle.points * U.pixelsize, U.dpi); font_id = blf_mono_font; } else { - BLI_assert(ELEM(field->format.style, UI_TIP_STYLE_NORMAL, UI_TIP_STYLE_HEADER)); + BLI_assert(ELEM( + field->format.style, uiTooltipFormat::Style::Normal, uiTooltipFormat::Style::Header)); font_id = data->fstyle.uifont_id; } w = BLF_width_ex(font_id, field->text, UI_TIP_STR_MAX, &info); @@ -1253,22 +1187,20 @@ static ARegion *ui_tooltip_create_with_data(bContext *C, /* Clamp to window bounds. */ { - /* Ensure at least 5 px above screen bounds - * UI_UNIT_Y is just a guess to be above the menu item */ - if (init_rect_overlap != NULL) { + /* Ensure at least 5 px above screen bounds. + * #UI_UNIT_Y is just a guess to be above the menu item. */ + if (init_rect_overlap != nullptr) { const int pad = max_ff(1.0f, U.pixelsize) * 5; - const rcti init_rect = { - .xmin = init_rect_overlap->xmin - pad, - .xmax = init_rect_overlap->xmax + pad, - .ymin = init_rect_overlap->ymin - pad, - .ymax = init_rect_overlap->ymax + pad, - }; - const rcti rect_clamp = { - .xmin = 0, - .xmax = winx, - .ymin = 0, - .ymax = winy, - }; + rcti init_rect; + init_rect.xmin = init_rect_overlap->xmin - pad; + init_rect.xmax = init_rect_overlap->xmax + pad; + init_rect.ymin = init_rect_overlap->ymin - pad; + init_rect.ymax = init_rect_overlap->ymax + pad; + rcti rect_clamp; + rect_clamp.xmin = 0; + rect_clamp.xmax = winx; + rect_clamp.ymin = 0; + rect_clamp.ymax = winy; /* try right. */ const int size_x = BLI_rcti_size_x(&rect_i); const int size_y = BLI_rcti_size_y(&rect_i); @@ -1348,12 +1280,11 @@ static ARegion *ui_tooltip_create_with_data(bContext *C, } else { const int pad = max_ff(1.0f, U.pixelsize) * 5; - const rcti rect_clamp = { - .xmin = pad, - .xmax = winx - pad, - .ymin = pad + (UI_UNIT_Y * 2), - .ymax = winy - pad, - }; + rcti rect_clamp; + rect_clamp.xmin = pad; + rect_clamp.xmax = winx - pad; + rect_clamp.ymin = pad + (UI_UNIT_Y * 2); + rect_clamp.ymax = winy - pad; int offset_dummy[2]; BLI_rcti_clamp(&rect_i, &rect_clamp, offset_dummy); } @@ -1368,7 +1299,7 @@ static ARegion *ui_tooltip_create_with_data(bContext *C, { /* Compensate for margin offset, visually this corrects the position. */ const int margin = UI_POPUP_MARGIN; - if (init_rect_overlap != NULL) { + if (init_rect_overlap != nullptr) { BLI_rcti_translate(&rect_i, margin, margin / 2); } @@ -1403,29 +1334,29 @@ ARegion *UI_tooltip_create_from_button_or_extra_icon( bContext *C, ARegion *butregion, uiBut *but, uiButExtraOpIcon *extra_icon, bool is_label) { wmWindow *win = CTX_wm_window(C); - /* aspect values that shrink text are likely unreadable */ + /* Aspect values that shrink text are likely unreadable. */ const float aspect = min_ff(1.0f, but->block->aspect); float init_position[2]; if (but->drawflag & UI_BUT_NO_TOOLTIP) { - return NULL; + return nullptr; } - uiTooltipData *data = NULL; + uiTooltipData *data = nullptr; - if (data == NULL) { + if (data == nullptr) { data = ui_tooltip_data_from_tool(C, but, is_label); } - if (data == NULL) { + if (data == nullptr) { data = ui_tooltip_data_from_button_or_extra_icon(C, but, extra_icon); } - if (data == NULL) { - data = ui_tooltip_data_from_button_or_extra_icon(C, but, NULL); + if (data == nullptr) { + data = ui_tooltip_data_from_button_or_extra_icon(C, but, nullptr); } - if (data == NULL) { - return NULL; + if (data == nullptr) { + return nullptr; } const bool is_no_overlap = UI_but_has_tooltip_label(but) || UI_but_is_tool(but); @@ -1454,31 +1385,30 @@ ARegion *UI_tooltip_create_from_button_or_extra_icon( } ARegion *region = ui_tooltip_create_with_data( - C, data, init_position, is_no_overlap ? &init_rect : NULL, aspect); + C, data, init_position, is_no_overlap ? &init_rect : nullptr, aspect); return region; } ARegion *UI_tooltip_create_from_button(bContext *C, ARegion *butregion, uiBut *but, bool is_label) { - return UI_tooltip_create_from_button_or_extra_icon(C, butregion, but, NULL, is_label); + return UI_tooltip_create_from_button_or_extra_icon(C, butregion, but, nullptr, is_label); } ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *gz) { wmWindow *win = CTX_wm_window(C); const float aspect = 1.0f; - float init_position[2] = {win->eventstate->xy[0], win->eventstate->xy[1]}; + float init_position[2] = {static_cast<float>(win->eventstate->xy[0]), + static_cast<float>(win->eventstate->xy[1])}; uiTooltipData *data = ui_tooltip_data_from_gizmo(C, gz); - if (data == NULL) { - return NULL; + if (data == nullptr) { + return nullptr; } - /* TODO(harley): - * Julian preferred that the gizmo callback return the 3D bounding box - * which we then project to 2D here. Would make a nice improvement. - */ + /* TODO(@harley): Julian preferred that the gizmo callback return the 3D bounding box + * which we then project to 2D here. Would make a nice improvement. */ if (gz->type->screen_bounds_get) { rcti bounds; if (gz->type->screen_bounds_get(C, gz, &bounds)) { @@ -1487,46 +1417,34 @@ ARegion *UI_tooltip_create_from_gizmo(bContext *C, wmGizmo *gz) } } - return ui_tooltip_create_with_data(C, data, init_position, NULL, aspect); + return ui_tooltip_create_with_data(C, data, init_position, nullptr, aspect); } static uiTooltipData *ui_tooltip_data_from_search_item_tooltip_data( const uiSearchItemTooltipData *item_tooltip_data) { - uiTooltipData *data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData"); + uiTooltipData *data = MEM_cnew<uiTooltipData>(__func__); if (item_tooltip_data->description[0]) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_HEADER, - .color_id = UI_TIP_LC_NORMAL, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Header, uiTooltipFormat::ColorID::Normal, true); field->text = BLI_strdup(item_tooltip_data->description); } if (item_tooltip_data->name && item_tooltip_data->name[0]) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_VALUE, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Value, true); field->text = BLI_strdup(item_tooltip_data->name); } if (item_tooltip_data->hint[0]) { - uiTooltipField *field = text_field_add(data, - &(uiTooltipFormat){ - .style = UI_TIP_STYLE_NORMAL, - .color_id = UI_TIP_LC_NORMAL, - .is_pad = true, - }); + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Normal, true); field->text = BLI_strdup(item_tooltip_data->hint); } if (data->fields_len == 0) { MEM_freeN(data); - return NULL; + return nullptr; } return data; } @@ -1538,8 +1456,8 @@ ARegion *UI_tooltip_create_from_search_item_generic( const uiSearchItemTooltipData *item_tooltip_data) { uiTooltipData *data = ui_tooltip_data_from_search_item_tooltip_data(item_tooltip_data); - if (data == NULL) { - return NULL; + if (data == nullptr) { + return nullptr; } const float aspect = 1.0f; @@ -1548,7 +1466,7 @@ ARegion *UI_tooltip_create_from_search_item_generic( init_position[0] = win->eventstate->xy[0]; init_position[1] = item_rect->ymin + searchbox_region->winrct.ymin - (UI_POPUP_MARGIN / 2); - return ui_tooltip_create_with_data(C, data, init_position, NULL, aspect); + return ui_tooltip_create_with_data(C, data, init_position, nullptr, aspect); } void UI_tooltip_free(bContext *C, bScreen *screen, ARegion *region) diff --git a/source/blender/editors/interface/interface_regions.cc b/source/blender/editors/interface/interface_regions.cc index 1a2c1f7919c..1770805cf59 100644 --- a/source/blender/editors/interface/interface_regions.cc +++ b/source/blender/editors/interface/interface_regions.cc @@ -21,7 +21,7 @@ #include "ED_screen.h" -#include "interface_regions_intern.h" +#include "interface_regions_intern.hh" ARegion *ui_region_temp_add(bScreen *screen) { diff --git a/source/blender/editors/interface/interface_regions_intern.h b/source/blender/editors/interface/interface_regions_intern.hh index 2ed2cb3d68b..6287a031f5c 100644 --- a/source/blender/editors/interface/interface_regions_intern.h +++ b/source/blender/editors/interface/interface_regions_intern.hh @@ -3,23 +3,16 @@ /** \file * \ingroup edinterface * - * Share between interface_region_*.c files. + * Share between interface_region_*.cc files. */ #pragma once -#ifdef __cplusplus -extern "C" { -#endif - -/* interface_region_menu_popup.c */ +/* interface_region_menu_popup.cc */ uint ui_popup_menu_hash(const char *str); -/* interface_regions_intern.h */ +/* interface_regions.cc */ + ARegion *ui_region_temp_add(bScreen *screen); void ui_region_temp_remove(struct bContext *C, bScreen *screen, ARegion *region); - -#ifdef __cplusplus -} -#endif diff --git a/source/blender/editors/interface/interface_template_asset_view.cc b/source/blender/editors/interface/interface_template_asset_view.cc index 8588c7cabc0..3147deb5ad1 100644 --- a/source/blender/editors/interface/interface_template_asset_view.cc +++ b/source/blender/editors/interface/interface_template_asset_view.cc @@ -66,7 +66,7 @@ static void asset_view_item_but_drag_set(uiBut *but, } static void asset_view_draw_item(uiList *ui_list, - bContext *UNUSED(C), + const bContext *UNUSED(C), uiLayout *layout, PointerRNA *UNUSED(dataptr), PointerRNA *itemptr, @@ -183,7 +183,7 @@ static void asset_view_template_refresh_asset_collection( } void uiTemplateAssetView(uiLayout *layout, - bContext *C, + const bContext *C, const char *list_id, PointerRNA *asset_library_dataptr, const char *asset_library_propname, diff --git a/source/blender/editors/interface/interface_template_list.cc b/source/blender/editors/interface/interface_template_list.cc index e0b6bbb34c4..f0c91588f98 100644 --- a/source/blender/editors/interface/interface_template_list.cc +++ b/source/blender/editors/interface/interface_template_list.cc @@ -83,7 +83,7 @@ struct TemplateListVisualInfo { }; static void uilist_draw_item_default(struct uiList *ui_list, - struct bContext *UNUSED(C), + const struct bContext *UNUSED(C), struct uiLayout *layout, struct PointerRNA *UNUSED(dataptr), struct PointerRNA *itemptr, @@ -114,7 +114,7 @@ static void uilist_draw_item_default(struct uiList *ui_list, } static void uilist_draw_filter_default(struct uiList *ui_list, - struct bContext *UNUSED(C), + const struct bContext *UNUSED(C), struct uiLayout *layout) { PointerRNA listptr; @@ -160,7 +160,7 @@ static int cmpstringp(const void *p1, const void *p2) } static void uilist_filter_items_default(struct uiList *ui_list, - struct bContext *UNUSED(C), + const struct bContext *UNUSED(C), struct PointerRNA *dataptr, const char *propname) { @@ -434,7 +434,7 @@ static void ui_template_list_collect_items(PointerRNA *list_ptr, /** * Create the UI-list representation of the list items, sorted and filtered if needed. */ -static void ui_template_list_collect_display_items(bContext *C, +static void ui_template_list_collect_display_items(const bContext *C, uiList *ui_list, TemplateListInputData *input_data, const uiListFilterItemsFunc filter_items_fn, @@ -601,7 +601,7 @@ static char *uilist_item_tooltip_func(bContext *UNUSED(C), void *argN, const cha /** * \note that \a layout_type may be null. */ -static uiList *ui_list_ensure(bContext *C, +static uiList *ui_list_ensure(const bContext *C, uiListType *ui_list_type, const char *list_id, int layout_type, @@ -656,7 +656,7 @@ static uiList *ui_list_ensure(bContext *C, return ui_list; } -static void ui_template_list_layout_draw(bContext *C, +static void ui_template_list_layout_draw(const bContext *C, uiList *ui_list, uiLayout *layout, TemplateListInputData *input_data, @@ -1156,7 +1156,7 @@ static void ui_template_list_layout_draw(bContext *C, } uiList *uiTemplateList_ex(uiLayout *layout, - bContext *C, + const bContext *C, const char *listtype_name, const char *list_id, PointerRNA *dataptr, @@ -1227,7 +1227,7 @@ uiList *uiTemplateList_ex(uiLayout *layout, } void uiTemplateList(uiLayout *layout, - bContext *C, + const bContext *C, const char *listtype_name, const char *list_id, PointerRNA *dataptr, diff --git a/source/blender/editors/interface/interface_template_search_operator.c b/source/blender/editors/interface/interface_template_search_operator.cc index 41de2ab197d..0d0a5f01744 100644 --- a/source/blender/editors/interface/interface_template_search_operator.c +++ b/source/blender/editors/interface/interface_template_search_operator.cc @@ -7,14 +7,15 @@ * accessed via the #WM_OT_search_operator operator. */ -#include <string.h> +#include <cstring> #include "DNA_object_types.h" #include "DNA_scene_types.h" #include "DNA_texture_types.h" -#include "BLI_alloca.h" +#include "BLI_array.hh" #include "BLI_ghash.h" +#include "BLI_math_vec_types.hh" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -35,10 +36,10 @@ static void operator_search_exec_fn(bContext *C, void *UNUSED(arg1), void *arg2) { - wmOperatorType *ot = arg2; + wmOperatorType *ot = static_cast<wmOperatorType *>(arg2); if (ot) { - WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, NULL, NULL); + WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, nullptr, nullptr); } } @@ -53,19 +54,20 @@ static void operator_search_update_fn(const bContext *C, /* Prepare BLI_string_all_words_matched. */ const size_t str_len = strlen(str); const int words_max = BLI_string_max_possible_word_count(str_len); - int(*words)[2] = BLI_array_alloca(words, words_max); - const int words_len = BLI_string_find_split_words(str, str_len, ' ', words, words_max); + blender::Array<blender::int2> words(words_max); + const int words_len = BLI_string_find_split_words( + str, str_len, ' ', (int(*)[2])words.data(), words_max); for (WM_operatortype_iter(&iter); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - wmOperatorType *ot = BLI_ghashIterator_getValue(&iter); + wmOperatorType *ot = static_cast<wmOperatorType *>(BLI_ghashIterator_getValue(&iter)); const char *ot_ui_name = CTX_IFACE_(ot->translation_context, ot->name); if ((ot->flag & OPTYPE_INTERNAL) && (G.debug & G_DEBUG_WM) == 0) { continue; } - if (BLI_string_all_words_matched(ot_ui_name, str, words, words_len)) { + if (BLI_string_all_words_matched(ot_ui_name, str, (int(*)[2])words.data(), words_len)) { if (WM_operator_poll((bContext *)C, ot)) { char name[256]; const int len = strlen(ot_ui_name); @@ -78,7 +80,7 @@ static void operator_search_update_fn(const bContext *C, if (WM_key_event_operator_string(C, ot->idname, WM_OP_EXEC_DEFAULT, - NULL, + nullptr, true, &name[len + 1], sizeof(name) - len - 1)) { @@ -105,11 +107,11 @@ void UI_but_func_operator_search(uiBut *but) UI_but_func_search_set(but, ui_searchbox_create_operator, operator_search_update_fn, - NULL, + nullptr, false, - NULL, + nullptr, operator_search_exec_fn, - NULL); + nullptr); } void uiTemplateOperatorSearch(uiLayout *layout) diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index ac6dcbea052..cb3d0923348 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -6702,7 +6702,7 @@ void uiTemplateCacheFileTimeSettings(uiLayout *layout, PointerRNA *fileptr) } static void cache_file_layer_item(uiList *UNUSED(ui_list), - bContext *UNUSED(C), + const bContext *UNUSED(C), uiLayout *layout, PointerRNA *UNUSED(dataptr), PointerRNA *itemptr, diff --git a/source/blender/editors/interface/interface_undo.c b/source/blender/editors/interface/interface_undo.cc index e998eb6dbed..ec54b695cf7 100644 --- a/source/blender/editors/interface/interface_undo.c +++ b/source/blender/editors/interface/interface_undo.cc @@ -7,7 +7,7 @@ * Undo stack to use for UI widgets that manage their own editing state. */ -#include <string.h> +#include <cstring> #include "BLI_listbase.h" @@ -21,39 +21,39 @@ /** \name Text Field Undo Stack * \{ */ -typedef struct uiUndoStack_Text_State { +struct uiUndoStack_Text_State { struct uiUndoStack_Text_State *next, *prev; int cursor_index; char text[0]; -} uiUndoStack_Text_State; +}; -typedef struct uiUndoStack_Text { +struct uiUndoStack_Text { ListBase states; uiUndoStack_Text_State *current; -} uiUndoStack_Text; +}; static const char *ui_textedit_undo_impl(uiUndoStack_Text *stack, int *r_cursor_index) { /* Don't undo if no data has been pushed yet. */ - if (stack->current == NULL) { - return NULL; + if (stack->current == nullptr) { + return nullptr; } /* Travel backwards in the stack and copy information to the caller. */ - if (stack->current->prev != NULL) { + if (stack->current->prev != nullptr) { stack->current = stack->current->prev; *r_cursor_index = stack->current->cursor_index; return stack->current->text; } - return NULL; + return nullptr; } static const char *ui_textedit_redo_impl(uiUndoStack_Text *stack, int *r_cursor_index) { /* Don't redo if no data has been pushed yet. */ - if (stack->current == NULL) { - return NULL; + if (stack->current == nullptr) { + return nullptr; } /* Only redo if new data has not been entered since the last undo. */ @@ -63,7 +63,7 @@ static const char *ui_textedit_redo_impl(uiUndoStack_Text *stack, int *r_cursor_ *r_cursor_index = stack->current->cursor_index; return stack->current->text; } - return NULL; + return nullptr; } const char *ui_textedit_undo(uiUndoStack_Text *stack, int direction, int *r_cursor_index) @@ -78,7 +78,7 @@ const char *ui_textedit_undo(uiUndoStack_Text *stack, int direction, int *r_curs void ui_textedit_undo_push(uiUndoStack_Text *stack, const char *text, int cursor_index) { /* Clear all redo actions from the current state. */ - if (stack->current != NULL) { + if (stack->current != nullptr) { while (stack->current->next) { uiUndoStack_Text_State *state = stack->current->next; BLI_remlink(&stack->states, state); @@ -88,7 +88,8 @@ void ui_textedit_undo_push(uiUndoStack_Text *stack, const char *text, int cursor /* Create the new state. */ const int text_size = strlen(text) + 1; - stack->current = MEM_mallocN(sizeof(uiUndoStack_Text_State) + text_size, __func__); + stack->current = static_cast<uiUndoStack_Text_State *>( + MEM_mallocN(sizeof(uiUndoStack_Text_State) + text_size, __func__)); stack->current->cursor_index = cursor_index; memcpy(stack->current->text, text, text_size); BLI_addtail(&stack->states, stack->current); @@ -96,8 +97,8 @@ void ui_textedit_undo_push(uiUndoStack_Text *stack, const char *text, int cursor uiUndoStack_Text *ui_textedit_undo_stack_create(void) { - uiUndoStack_Text *stack = MEM_mallocN(sizeof(uiUndoStack_Text), __func__); - stack->current = NULL; + uiUndoStack_Text *stack = MEM_new<uiUndoStack_Text>(__func__); + stack->current = nullptr; BLI_listbase_clear(&stack->states); return stack; diff --git a/source/blender/editors/io/CMakeLists.txt b/source/blender/editors/io/CMakeLists.txt index a716c00d5d9..568ece00c4c 100644 --- a/source/blender/editors/io/CMakeLists.txt +++ b/source/blender/editors/io/CMakeLists.txt @@ -11,9 +11,9 @@ set(INC ../../io/collada ../../io/common ../../io/gpencil + ../../io/stl ../../io/usd ../../io/wavefront_obj - ../../io/stl ../../makesdna ../../makesrna ../../windowmanager @@ -33,8 +33,8 @@ set(SRC io_gpencil_utils.c io_obj.c io_ops.c - io_usd.c io_stl_ops.c + io_usd.c io_alembic.h io_cache.h @@ -42,8 +42,8 @@ set(SRC io_gpencil.h io_obj.h io_ops.h - io_usd.h io_stl_ops.h + io_usd.h ) set(LIB diff --git a/source/blender/editors/io/io_gpencil_import.c b/source/blender/editors/io/io_gpencil_import.c index 9ac64407dcf..b6fecfaf94e 100644 --- a/source/blender/editors/io/io_gpencil_import.c +++ b/source/blender/editors/io/io_gpencil_import.c @@ -9,6 +9,8 @@ # include "BLI_path_util.h" +# include "MEM_guardedalloc.h" + # include "DNA_gpencil_types.h" # include "DNA_space_types.h" @@ -63,7 +65,8 @@ static int wm_gpencil_import_svg_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); - if (!RNA_struct_property_is_set(op->ptr, "filepath")) { + if (!RNA_struct_property_is_set(op->ptr, "filepath") || + !(RNA_struct_find_property(op->ptr, "directory"))) { BKE_report(op->reports, RPT_ERROR, "No filename given"); return OPERATOR_CANCELLED; } @@ -75,9 +78,6 @@ static int wm_gpencil_import_svg_exec(bContext *C, wmOperator *op) } View3D *v3d = get_invoke_view3d(C); - char filename[FILE_MAX]; - RNA_string_get(op->ptr, "filepath", filename); - /* Set flags. */ int flag = 0; @@ -101,13 +101,31 @@ static int wm_gpencil_import_svg_exec(bContext *C, wmOperator *op) .resolution = resolution, }; - /* Do Import. */ - WM_cursor_wait(1); - const bool done = gpencil_io_import(filename, ¶ms); - WM_cursor_wait(0); - - if (!done) { - BKE_report(op->reports, RPT_WARNING, "Unable to import SVG"); + /* Loop all selected files to import them. All SVG imported shared the same import + * parameters, but they are created in separated grease pencil objects. */ + PropertyRNA *prop; + if ((prop = RNA_struct_find_property(op->ptr, "directory"))) { + char *directory = RNA_string_get_alloc(op->ptr, "directory", NULL, 0, NULL); + + if ((prop = RNA_struct_find_property(op->ptr, "files"))) { + char file_path[FILE_MAX]; + RNA_PROP_BEGIN (op->ptr, itemptr, prop) { + char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0, NULL); + BLI_join_dirfile(file_path, sizeof(file_path), directory, filename); + MEM_freeN(filename); + + /* Do Import. */ + WM_cursor_wait(1); + RNA_string_get(&itemptr, "name", params.filename); + const bool done = gpencil_io_import(file_path, ¶ms); + WM_cursor_wait(0); + if (!done) { + BKE_reportf(op->reports, RPT_WARNING, "Unable to import '%s'", file_path); + } + } + RNA_PROP_END; + } + MEM_freeN(directory); } return OPERATOR_FINISHED; @@ -149,10 +167,11 @@ void WM_OT_gpencil_import_svg(wmOperatorType *ot) ot->check = wm_gpencil_import_svg_common_check; WM_operator_properties_filesel(ot, - FILE_TYPE_OBJECT_IO, + FILE_TYPE_FOLDER | FILE_TYPE_OBJECT_IO, FILE_BLENDER, FILE_OPENFILE, - WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_SHOW_PROPS, + WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_SHOW_PROPS | + WM_FILESEL_DIRECTORY | WM_FILESEL_FILES, FILE_DEFAULTDISPLAY, FILE_SORT_DEFAULT); diff --git a/source/blender/editors/lattice/editlattice_undo.c b/source/blender/editors/lattice/editlattice_undo.c index 7615a57c8fe..8265225e08a 100644 --- a/source/blender/editors/lattice/editlattice_undo.c +++ b/source/blender/editors/lattice/editlattice_undo.c @@ -46,7 +46,7 @@ static CLG_LogRef LOG = {"ed.undo.lattice"}; /** \name Undo Conversion * \{ */ -/* TODO(Campbell): this could contain an entire 'Lattice' struct. */ +/* TODO(@campbellbarton): this could contain an entire 'Lattice' struct. */ typedef struct UndoLattice { BPoint *def; int pntsu, pntsv, pntsw, actbp; diff --git a/source/blender/editors/mesh/editface.cc b/source/blender/editors/mesh/editface.cc index b69cd8b8606..3608e162727 100644 --- a/source/blender/editors/mesh/editface.cc +++ b/source/blender/editors/mesh/editface.cc @@ -556,7 +556,7 @@ void paintvert_hide(bContext *C, Object *ob, const bool unselected) { Mesh *const me = BKE_mesh_from_object(ob); - if (me == NULL || me->totvert == 0) { + if (me == nullptr || me->totvert == 0) { return; } @@ -584,7 +584,7 @@ void paintvert_reveal(bContext *C, Object *ob, const bool select) { Mesh *const me = BKE_mesh_from_object(ob); - if (me == NULL || me->totvert == 0) { + if (me == nullptr || me->totvert == 0) { return; } diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index ac5530c8ea9..a0e20e4db8a 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -593,6 +593,31 @@ UvMapVert *BM_uv_vert_map_at_index(UvVertMap *vmap, uint v) return vmap->vert[v]; } +static void bm_uv_ensure_head_table(UvElementMap *element_map) +{ + if (element_map->head_table) { + return; + } + + /* For each UvElement, locate the "separate" UvElement that precedes it in the linked list. */ + element_map->head_table = MEM_mallocN(sizeof(*element_map->head_table) * element_map->total_uvs, + "uv_element_map_head_table"); + UvElement **head_table = element_map->head_table; + for (int i = 0; i < element_map->total_uvs; i++) { + UvElement *head = element_map->storage + i; + if (head->separate) { + UvElement *element = head; + while (element) { + head_table[element - element_map->storage] = head; + element = element->next; + if (element && element->separate) { + break; + } + } + } + } +} + #define INVALID_ISLAND ((unsigned int)-1) static void bm_uv_assign_island(UvElementMap *element_map, @@ -603,7 +628,7 @@ static void bm_uv_assign_island(UvElementMap *element_map, int islandbufsize) { element->island = nisland; - map[element - element_map->buf] = islandbufsize; + map[element - element_map->storage] = islandbufsize; /* Copy *element to islandbuf[islandbufsize]. */ islandbuf[islandbufsize].l = element->l; @@ -620,33 +645,19 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map, bool uv_selected, int cd_loop_uv_offset) { - int totuv = element_map->totalUVs; + bm_uv_ensure_head_table(element_map); - /* For each UvElement, locate the "separate" UvElement that precedes it in the linked list. */ - UvElement **head_table = MEM_mallocN(sizeof(*head_table) * totuv, "uv_island_head_table"); - for (int i = 0; i < totuv; i++) { - UvElement *head = element_map->buf + i; - if (head->separate) { - UvElement *element = head; - while (element) { - head_table[element - element_map->buf] = head; - element = element->next; - if (element && element->separate) { - break; - } - } - } - } + int total_uvs = element_map->total_uvs; /* Depth first search the graph, building islands as we go. */ int nislands = 0; int islandbufsize = 0; - int stack_upper_bound = totuv; + int stack_upper_bound = total_uvs; UvElement **stack_uv = MEM_mallocN(sizeof(*stack_uv) * stack_upper_bound, "uv_island_element_stack"); int stacksize_uv = 0; - for (int i = 0; i < totuv; i++) { - UvElement *element = element_map->buf + i; + for (int i = 0; i < total_uvs; i++) { + UvElement *element = element_map->storage + i; if (element->island != INVALID_ISLAND) { /* Unique UV (element and all it's children) are already part of an island. */ continue; @@ -676,7 +687,7 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map, if (!uv_selected || uvedit_edge_select_test(scene, element->l, cd_loop_uv_offset)) { UvElement *next = BM_uv_element_get(element_map, element->l->next->f, element->l->next); if (next->island == INVALID_ISLAND) { - UvElement *tail = head_table[next - element_map->buf]; + UvElement *tail = element_map->head_table[next - element_map->storage]; stack_uv[stacksize_uv++] = tail; while (tail) { bm_uv_assign_island(element_map, tail, nislands, map, islandbuf, islandbufsize++); @@ -692,7 +703,7 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map, if (!uv_selected || uvedit_edge_select_test(scene, element->l->prev, cd_loop_uv_offset)) { UvElement *prev = BM_uv_element_get(element_map, element->l->prev->f, element->l->prev); if (prev->island == INVALID_ISLAND) { - UvElement *tail = head_table[prev - element_map->buf]; + UvElement *tail = element_map->head_table[prev - element_map->storage]; stack_uv[stacksize_uv++] = tail; while (tail) { bm_uv_assign_island(element_map, tail, nislands, map, islandbuf, islandbufsize++); @@ -713,14 +724,128 @@ static int bm_uv_edge_select_build_islands(UvElementMap *element_map, } nislands++; } - BLI_assert(islandbufsize == totuv); + BLI_assert(islandbufsize == total_uvs); MEM_SAFE_FREE(stack_uv); - MEM_SAFE_FREE(head_table); + MEM_SAFE_FREE(element_map->head_table); return nislands; } +static void bm_uv_build_islands(UvElementMap *element_map, + BMesh *bm, + const Scene *scene, + bool uv_selected) +{ + int totuv = element_map->total_uvs; + int nislands = 0; + int islandbufsize = 0; + + /* map holds the map from current vmap->buf to the new, sorted map */ + uint *map = MEM_mallocN(sizeof(*map) * totuv, "uvelement_remap"); + BMFace **stack = MEM_mallocN(sizeof(*stack) * bm->totface, "uv_island_face_stack"); + UvElement *islandbuf = MEM_callocN(sizeof(*islandbuf) * totuv, "uvelement_island_buffer"); + /* Island number for BMFaces. */ + int *island_number = MEM_callocN(sizeof(*island_number) * bm->totface, "uv_island_number_face"); + copy_vn_i(island_number, bm->totface, INVALID_ISLAND); + + const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + + const bool use_uv_edge_connectivity = scene->toolsettings->uv_flag & UV_SYNC_SELECTION ? + scene->toolsettings->selectmode & SCE_SELECT_EDGE : + scene->toolsettings->uv_selectmode & UV_SELECT_EDGE; + if (use_uv_edge_connectivity) { + nislands = bm_uv_edge_select_build_islands( + element_map, scene, islandbuf, map, uv_selected, cd_loop_uv_offset); + islandbufsize = totuv; + } + + for (int i = 0; i < totuv; i++) { + if (element_map->storage[i].island == INVALID_ISLAND) { + int stacksize = 0; + element_map->storage[i].island = nislands; + stack[0] = element_map->storage[i].l->f; + island_number[BM_elem_index_get(stack[0])] = nislands; + stacksize = 1; + + while (stacksize > 0) { + BMFace *efa = stack[--stacksize]; + + BMLoop *l; + BMIter liter; + BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { + if (uv_selected && !uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { + continue; + } + + UvElement *initelement = element_map->vertex[BM_elem_index_get(l->v)]; + + for (UvElement *element = initelement; element; element = element->next) { + if (element->separate) { + initelement = element; + } + + if (element->l->f == efa) { + /* found the uv corresponding to our face and vertex. + * Now fill it to the buffer */ + bm_uv_assign_island(element_map, element, nislands, map, islandbuf, islandbufsize++); + + for (element = initelement; element; element = element->next) { + if (element->separate && element != initelement) { + break; + } + + if (island_number[BM_elem_index_get(element->l->f)] == INVALID_ISLAND) { + stack[stacksize++] = element->l->f; + island_number[BM_elem_index_get(element->l->f)] = nislands; + } + } + break; + } + } + } + } + + nislands++; + } + } + + MEM_SAFE_FREE(island_number); + + /* remap */ + for (int i = 0; i < bm->totvert; i++) { + /* important since we may do selection only. Some of these may be NULL */ + if (element_map->vertex[i]) { + element_map->vertex[i] = &islandbuf[map[element_map->vertex[i] - element_map->storage]]; + } + } + + element_map->islandIndices = MEM_callocN(sizeof(*element_map->islandIndices) * nislands, + "UvElementMap_island_indices"); + int j = 0; + for (int i = 0; i < totuv; i++) { + UvElement *element = element_map->storage[i].next; + if (element == NULL) { + islandbuf[map[i]].next = NULL; + } + else { + islandbuf[map[i]].next = &islandbuf[map[element - element_map->storage]]; + } + + if (islandbuf[i].island != j) { + j++; + element_map->islandIndices[j] = i; + } + } + + MEM_SAFE_FREE(element_map->storage); + element_map->storage = islandbuf; + islandbuf = NULL; + element_map->totalIslands = nislands; + MEM_SAFE_FREE(stack); + MEM_SAFE_FREE(map); +} + UvElementMap *BM_uv_element_map_create(BMesh *bm, const Scene *scene, const bool uv_selected, @@ -732,26 +857,18 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, BMVert *ev; BMFace *efa; - BMLoop *l; BMIter iter, liter; - /* vars from original func */ - UvElementMap *element_map; - UvElement *buf; - bool *winding = NULL; BLI_buffer_declare_static(vec2f, tf_uv_buf, BLI_BUFFER_NOP, BM_DEFAULT_NGON_STACK_SIZE); - MLoopUV *luv; - int totverts, totfaces, i, totuv, j; - const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV); + if (cd_loop_uv_offset < 0) { + return NULL; + } BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE); - totfaces = bm->totface; - totverts = bm->totvert; - totuv = 0; - - /* generate UvElement array */ + /* Count total uvs. */ + int totuv = 0; BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { continue; @@ -765,6 +882,7 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, totuv += efa->len; } else { + BMLoop *l; BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { totuv++; @@ -777,17 +895,17 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, return NULL; } - element_map = (UvElementMap *)MEM_callocN(sizeof(*element_map), "UvElementMap"); - element_map->totalUVs = totuv; - element_map->vert = (UvElement **)MEM_callocN(sizeof(*element_map->vert) * totverts, - "UvElementVerts"); - buf = element_map->buf = (UvElement *)MEM_callocN(sizeof(*element_map->buf) * totuv, - "UvElement"); + UvElementMap *element_map = (UvElementMap *)MEM_callocN(sizeof(*element_map), "UvElementMap"); + element_map->total_uvs = totuv; + element_map->vertex = (UvElement **)MEM_callocN(sizeof(*element_map->vertex) * bm->totvert, + "UvElementVerts"); + element_map->storage = (UvElement *)MEM_callocN(sizeof(*element_map->storage) * totuv, + "UvElement"); - if (use_winding) { - winding = MEM_callocN(sizeof(*winding) * totfaces, "winding"); - } + bool *winding = use_winding ? MEM_callocN(sizeof(*winding) * bm->totface, "winding") : NULL; + UvElement *buf = element_map->storage; + int j; BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, j) { if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { @@ -804,18 +922,20 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, tf_uv = (float(*)[2])BLI_buffer_reinit_data(&tf_uv_buf, vec2f, efa->len); } + int i; + BMLoop *l; BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) { if (uv_selected && !uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { continue; } buf->l = l; - buf->separate = 0; buf->island = INVALID_ISLAND; buf->loop_of_poly_index = i; - buf->next = element_map->vert[BM_elem_index_get(l->v)]; - element_map->vert[BM_elem_index_get(l->v)] = buf; + /* Insert to head of linked list associated with BMVert. */ + buf->next = element_map->vertex[BM_elem_index_get(l->v)]; + element_map->vertex[BM_elem_index_get(l->v)] = buf; if (use_winding) { luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); @@ -829,43 +949,54 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, winding[j] = cross_poly_v2(tf_uv, efa->len) > 0; } } + BLI_buffer_free(&tf_uv_buf); - /* sort individual uvs for each vert */ - BM_ITER_MESH_INDEX (ev, &iter, bm, BM_VERTS_OF_MESH, i) { - UvElement *newvlist = NULL, *vlist = element_map->vert[i]; - UvElement *iterv, *v, *lastv, *next; - const float *uv, *uv2; - bool uv_vert_sel, uv2_vert_sel; - + /* For each BMVert, sort associated linked list into unique uvs. */ + int ev_index; + BM_ITER_MESH_INDEX (ev, &iter, bm, BM_VERTS_OF_MESH, ev_index) { + UvElement *newvlist = NULL; + UvElement *vlist = element_map->vertex[ev_index]; while (vlist) { - v = vlist; + + /* Detach head from unsorted list. */ + UvElement *v = vlist; vlist = vlist->next; v->next = newvlist; newvlist = v; - l = v->l; - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - uv = luv->uv; - uv_vert_sel = uvedit_uv_select_test(scene, l, cd_loop_uv_offset); + luv = BM_ELEM_CD_GET_VOID_P(v->l, cd_loop_uv_offset); + const float *uv = luv->uv; + bool uv_vert_sel = uvedit_uv_select_test(scene, v->l, cd_loop_uv_offset); - lastv = NULL; - iterv = vlist; + UvElement *lastv = NULL; + UvElement *iterv = vlist; + /* Scan through unsorted list, finding UvElements which are connected to `v`. */ while (iterv) { - next = iterv->next; + UvElement *next = iterv->next; + luv = BM_ELEM_CD_GET_VOID_P(iterv->l, cd_loop_uv_offset); - l = iterv->l; - luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset); - uv2 = luv->uv; - uv2_vert_sel = uvedit_uv_select_test(scene, l, cd_loop_uv_offset); + bool connected = true; /* Assume connected unless we can prove otherwise. */ + + if (connected) { + /* Are the two UVs close together? */ + const float *uv2 = luv->uv; + connected = compare_v2v2(uv2, uv, STD_UV_CONNECT_LIMIT); + } + + if (connected) { + /* Check if the uv loops share the same selection state (if not, they are not connected + * as they have been ripped or other edit commands have separated them). */ + const bool uv2_vert_sel = uvedit_uv_select_test(scene, iterv->l, cd_loop_uv_offset); + connected = (uv_vert_sel == uv2_vert_sel); + } - /* Check if the uv loops share the same selection state (if not, they are not connected as - * they have been ripped or other edit commands have separated them). */ - const bool connected = (uv_vert_sel == uv2_vert_sel) && - compare_v2v2(uv2, uv, STD_UV_CONNECT_LIMIT); + if (connected && use_winding) { + connected = winding[BM_elem_index_get(iterv->l->f)] == + winding[BM_elem_index_get(v->l->f)]; + } - if (connected && (!use_winding || winding[BM_elem_index_get(iterv->l->f)] == - winding[BM_elem_index_get(v->l->f)])) { + if (connected) { if (lastv) { lastv->next = next; } @@ -882,130 +1013,30 @@ UvElementMap *BM_uv_element_map_create(BMesh *bm, iterv = next; } - newvlist->separate = 1; + element_map->total_unique_uvs++; + newvlist->separate = true; } - element_map->vert[i] = newvlist; + /* Write back sorted list. */ + element_map->vertex[ev_index] = newvlist; } - if (use_winding) { - MEM_freeN(winding); - } + MEM_SAFE_FREE(winding); + /* at this point, every UvElement in vert points to a UvElement sharing the same vertex. + * Now we should sort uv's in islands. */ if (do_islands) { - uint *map; - BMFace **stack; - int stacksize = 0; - UvElement *islandbuf; - /* island number for faces */ - int *island_number = NULL; - - int nislands = 0, islandbufsize = 0; - - /* map holds the map from current vmap->buf to the new, sorted map */ - map = MEM_mallocN(sizeof(*map) * totuv, "uvelement_remap"); - stack = MEM_mallocN(sizeof(*stack) * bm->totface, "uv_island_face_stack"); - islandbuf = MEM_callocN(sizeof(*islandbuf) * totuv, "uvelement_island_buffer"); - island_number = MEM_mallocN(sizeof(*island_number) * totfaces, "uv_island_number_face"); - copy_vn_i(island_number, totfaces, INVALID_ISLAND); - - const bool use_uv_edge_connectivity = scene->toolsettings->uv_flag & UV_SYNC_SELECTION ? - scene->toolsettings->selectmode & SCE_SELECT_EDGE : - scene->toolsettings->uv_selectmode & UV_SELECT_EDGE; - if (use_uv_edge_connectivity) { - nislands = bm_uv_edge_select_build_islands( - element_map, scene, islandbuf, map, uv_selected, cd_loop_uv_offset); - islandbufsize = totuv; - } - - /* at this point, every UvElement in vert points to a UvElement sharing the same vertex. - * Now we should sort uv's in islands. */ - for (i = 0; i < totuv; i++) { - if (element_map->buf[i].island == INVALID_ISLAND) { - element_map->buf[i].island = nislands; - stack[0] = element_map->buf[i].l->f; - island_number[BM_elem_index_get(stack[0])] = nislands; - stacksize = 1; - - while (stacksize > 0) { - efa = stack[--stacksize]; - - BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { - if (uv_selected && !uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) { - continue; - } - - UvElement *element, *initelement = element_map->vert[BM_elem_index_get(l->v)]; - - for (element = initelement; element; element = element->next) { - if (element->separate) { - initelement = element; - } - - if (element->l->f == efa) { - /* found the uv corresponding to our face and vertex. - * Now fill it to the buffer */ - bm_uv_assign_island( - element_map, element, nislands, map, islandbuf, islandbufsize++); - - for (element = initelement; element; element = element->next) { - if (element->separate && element != initelement) { - break; - } - - if (island_number[BM_elem_index_get(element->l->f)] == INVALID_ISLAND) { - stack[stacksize++] = element->l->f; - island_number[BM_elem_index_get(element->l->f)] = nislands; - } - } - break; - } - } - } - } - - nislands++; - } - } - - MEM_freeN(island_number); - - /* remap */ - for (i = 0; i < bm->totvert; i++) { - /* important since we may do selection only. Some of these may be NULL */ - if (element_map->vert[i]) { - element_map->vert[i] = &islandbuf[map[element_map->vert[i] - element_map->buf]]; - } - } - - element_map->islandIndices = MEM_callocN(sizeof(*element_map->islandIndices) * nislands, - "UvElementMap_island_indices"); - j = 0; - for (i = 0; i < totuv; i++) { - UvElement *element = element_map->buf[i].next; - if (element == NULL) { - islandbuf[map[i]].next = NULL; - } - else { - islandbuf[map[i]].next = &islandbuf[map[element - element_map->buf]]; - } + bm_uv_build_islands(element_map, bm, scene, uv_selected); + } - if (islandbuf[i].island != j) { - j++; - element_map->islandIndices[j] = i; - } + /* TODO: Confirm element_map->total_unique_uvs doesn't require recalculating. */ + element_map->total_unique_uvs = 0; + for (int i = 0; i < element_map->total_uvs; i++) { + if (element_map->storage[i].separate) { + element_map->total_unique_uvs++; } - - MEM_freeN(element_map->buf); - - element_map->buf = islandbuf; - element_map->totalIslands = nislands; - MEM_freeN(stack); - MEM_freeN(map); } - BLI_buffer_free(&tf_uv_buf); - return element_map; } @@ -1025,30 +1056,36 @@ void BM_uv_vert_map_free(UvVertMap *vmap) void BM_uv_element_map_free(UvElementMap *element_map) { if (element_map) { - if (element_map->vert) { - MEM_freeN(element_map->vert); - } - if (element_map->buf) { - MEM_freeN(element_map->buf); - } - if (element_map->islandIndices) { - MEM_freeN(element_map->islandIndices); - } - MEM_freeN(element_map); + MEM_SAFE_FREE(element_map->storage); + MEM_SAFE_FREE(element_map->vertex); + MEM_SAFE_FREE(element_map->head_table); + MEM_SAFE_FREE(element_map->islandIndices); + MEM_SAFE_FREE(element_map); } } -UvElement *BM_uv_element_get(UvElementMap *map, BMFace *efa, BMLoop *l) +UvElement *BM_uv_element_get(UvElementMap *element_map, BMFace *efa, BMLoop *l) { - for (UvElement *element = map->vert[BM_elem_index_get(l->v)]; element; element = element->next) { + UvElement *element = element_map->vertex[BM_elem_index_get(l->v)]; + while (element) { if (element->l->f == efa) { return element; } + element = element->next; } return NULL; } +UvElement *BM_uv_element_get_head(UvElementMap *element_map, UvElement *child) +{ + if (!child) { + return NULL; + } + + return element_map->vertex[BM_elem_index_get(child->l->v)]; +} + /** \} */ /* -------------------------------------------------------------------- */ @@ -1518,7 +1555,7 @@ void EDBM_update(Mesh *mesh, const struct EDBMUpdate_Params *params) } if (params->is_destructive) { - /* TODO(campbell): we may be able to remove this now! */ + /* TODO(@campbellbarton): we may be able to remove this now! */ // BM_mesh_elem_table_free(em->bm, BM_ALL_NOLOOP); } else { diff --git a/source/blender/editors/mesh/mesh_data.cc b/source/blender/editors/mesh/mesh_data.cc index 67834bf05ce..971fab1508e 100644 --- a/source/blender/editors/mesh/mesh_data.cc +++ b/source/blender/editors/mesh/mesh_data.cc @@ -444,44 +444,6 @@ bool ED_mesh_color_ensure(Mesh *me, const char *name) return (layer != nullptr); } -bool ED_mesh_color_remove_index(Mesh *me, const int n) -{ - CustomData *ldata = GET_CD_DATA(me, ldata); - CustomDataLayer *cdl; - int index; - - index = CustomData_get_layer_index_n(ldata, CD_PROP_BYTE_COLOR, n); - cdl = (index == -1) ? nullptr : &ldata->layers[index]; - - if (!cdl) { - return false; - } - - delete_customdata_layer(me, cdl); - DEG_id_tag_update(&me->id, 0); - WM_main_add_notifier(NC_GEOM | ND_DATA, me); - - return true; -} -bool ED_mesh_color_remove_active(Mesh *me) -{ - CustomData *ldata = GET_CD_DATA(me, ldata); - const int n = CustomData_get_active_layer(ldata, CD_PROP_BYTE_COLOR); - if (n != -1) { - return ED_mesh_color_remove_index(me, n); - } - return false; -} -bool ED_mesh_color_remove_named(Mesh *me, const char *name) -{ - CustomData *ldata = GET_CD_DATA(me, ldata); - const int n = CustomData_get_named_layer(ldata, CD_PROP_BYTE_COLOR, name); - if (n != -1) { - return ED_mesh_color_remove_index(me, n); - } - return false; -} - /*********************** General poll ************************/ static bool layers_poll(bContext *C) @@ -494,25 +456,7 @@ static bool layers_poll(bContext *C) /*********************** Sculpt Vertex colors operators ************************/ -static bool sculpt_vertex_color_remove_poll(bContext *C) -{ - if (!layers_poll(C)) { - return false; - } - - Object *ob = ED_object_context(C); - Mesh *me = static_cast<Mesh *>(ob->data); - CustomData *vdata = GET_CD_DATA(me, vdata); - const int active = CustomData_get_active_layer(vdata, CD_PROP_COLOR); - if (active != -1) { - return true; - } - - return false; -} - -int ED_mesh_sculpt_color_add( - Mesh *me, const char *name, const bool active_set, const bool do_init, ReportList *reports) +int ED_mesh_sculpt_color_add(Mesh *me, const char *name, const bool do_init, ReportList *reports) { /* NOTE: keep in sync with #ED_mesh_uv_add. */ @@ -536,7 +480,7 @@ int ED_mesh_sculpt_color_add( const int layernum_dst = CustomData_get_active_layer(&em->bm->vdata, CD_PROP_COLOR); BM_data_layer_copy(em->bm, &em->bm->vdata, CD_PROP_COLOR, layernum_dst, layernum); } - if (active_set || layernum == 0) { + if (layernum == 0) { CustomData_set_layer_active(&em->bm->vdata, CD_PROP_COLOR, layernum); } } @@ -559,7 +503,7 @@ int ED_mesh_sculpt_color_add( &me->vdata, CD_PROP_COLOR, CD_DEFAULT, nullptr, me->totvert, name); } - if (active_set || layernum == 0) { + if (layernum == 0) { CustomData_set_layer_active(&me->vdata, CD_PROP_COLOR, layernum); } @@ -572,58 +516,6 @@ int ED_mesh_sculpt_color_add( return layernum; } -bool ED_mesh_sculpt_color_ensure(Mesh *me, const char *name) -{ - BLI_assert(me->edit_mesh == nullptr); - - if (me->totvert && !CustomData_has_layer(&me->vdata, CD_PROP_COLOR)) { - CustomData_add_layer_named(&me->vdata, CD_PROP_COLOR, CD_DEFAULT, nullptr, me->totvert, name); - BKE_mesh_update_customdata_pointers(me, true); - } - - DEG_id_tag_update(&me->id, 0); - - return (me->mloopcol != nullptr); -} - -bool ED_mesh_sculpt_color_remove_index(Mesh *me, const int n) -{ - CustomData *vdata = GET_CD_DATA(me, vdata); - CustomDataLayer *cdl; - int index; - - index = CustomData_get_layer_index_n(vdata, CD_PROP_COLOR, n); - cdl = (index == -1) ? nullptr : &vdata->layers[index]; - - if (!cdl) { - return false; - } - - delete_customdata_layer(me, cdl); - DEG_id_tag_update(&me->id, 0); - WM_main_add_notifier(NC_GEOM | ND_DATA, me); - - return true; -} -bool ED_mesh_sculpt_color_remove_active(Mesh *me) -{ - CustomData *vdata = GET_CD_DATA(me, vdata); - const int n = CustomData_get_active_layer(vdata, CD_PROP_COLOR); - if (n != -1) { - return ED_mesh_sculpt_color_remove_index(me, n); - } - return false; -} -bool ED_mesh_sculpt_color_remove_named(Mesh *me, const char *name) -{ - CustomData *vdata = GET_CD_DATA(me, vdata); - const int n = CustomData_get_named_layer(vdata, CD_PROP_COLOR, name); - if (n != -1) { - return ED_mesh_sculpt_color_remove_index(me, n); - } - return false; -} - /*********************** UV texture operators ************************/ static bool uv_texture_remove_poll(bContext *C) @@ -709,135 +601,6 @@ void MESH_OT_uv_texture_remove(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } -/*********************** vertex color operators ************************/ - -static bool vertex_color_remove_poll(bContext *C) -{ - if (!layers_poll(C)) { - return false; - } - - Object *ob = ED_object_context(C); - Mesh *me = static_cast<Mesh *>(ob->data); - CustomData *ldata = GET_CD_DATA(me, ldata); - const int active = CustomData_get_active_layer(ldata, CD_PROP_BYTE_COLOR); - if (active != -1) { - return true; - } - - return false; -} - -static int mesh_vertex_color_add_exec(bContext *C, wmOperator *op) -{ - Object *ob = ED_object_context(C); - Mesh *me = static_cast<Mesh *>(ob->data); - - if (ED_mesh_color_add(me, nullptr, true, true, op->reports) == -1) { - return OPERATOR_CANCELLED; - } - - return OPERATOR_FINISHED; -} - -void MESH_OT_vertex_color_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Add Vertex Color"; - ot->description = "Add vertex color layer"; - ot->idname = "MESH_OT_vertex_color_add"; - - /* api callbacks */ - ot->poll = layers_poll; - ot->exec = mesh_vertex_color_add_exec; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -static int mesh_vertex_color_remove_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *ob = ED_object_context(C); - Mesh *me = static_cast<Mesh *>(ob->data); - - if (!ED_mesh_color_remove_active(me)) { - return OPERATOR_CANCELLED; - } - - return OPERATOR_FINISHED; -} - -void MESH_OT_vertex_color_remove(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Remove Vertex Color"; - ot->description = "Remove vertex color layer"; - ot->idname = "MESH_OT_vertex_color_remove"; - - /* api callbacks */ - ot->exec = mesh_vertex_color_remove_exec; - ot->poll = vertex_color_remove_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/*********************** Sculpt Vertex Color Operators ************************/ - -static int mesh_sculpt_vertex_color_add_exec(bContext *C, wmOperator *op) -{ - Object *ob = ED_object_context(C); - Mesh *me = static_cast<Mesh *>(ob->data); - - if (ED_mesh_sculpt_color_add(me, nullptr, true, true, op->reports) == -1) { - return OPERATOR_CANCELLED; - } - - return OPERATOR_FINISHED; -} - -void MESH_OT_sculpt_vertex_color_add(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Add Sculpt Vertex Color"; - ot->description = "Add vertex color layer"; - ot->idname = "MESH_OT_sculpt_vertex_color_add"; - - /* api callbacks */ - ot->poll = layers_poll; - ot->exec = mesh_sculpt_vertex_color_add_exec; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -static int mesh_sculpt_vertex_color_remove_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *ob = ED_object_context(C); - Mesh *me = static_cast<Mesh *>(ob->data); - - if (!ED_mesh_sculpt_color_remove_active(me)) { - return OPERATOR_CANCELLED; - } - - return OPERATOR_FINISHED; -} - -void MESH_OT_sculpt_vertex_color_remove(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Remove Sculpt Vertex Color"; - ot->description = "Remove vertex color layer"; - ot->idname = "MESH_OT_sculpt_vertex_color_remove"; - - /* api callbacks */ - ot->exec = mesh_sculpt_vertex_color_remove_exec; - ot->poll = sculpt_vertex_color_remove_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - /* *** CustomData clear functions, we need an operator for each *** */ static int mesh_customdata_clear_exec__internal(bContext *C, char htype, int type) diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 303234df48c..7c8dbffeb31 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -308,10 +308,6 @@ void MESH_OT_mark_freestyle_face(struct wmOperatorType *ot); void MESH_OT_uv_texture_add(struct wmOperatorType *ot); void MESH_OT_uv_texture_remove(struct wmOperatorType *ot); -void MESH_OT_vertex_color_add(struct wmOperatorType *ot); -void MESH_OT_vertex_color_remove(struct wmOperatorType *ot); -void MESH_OT_sculpt_vertex_color_add(struct wmOperatorType *ot); -void MESH_OT_sculpt_vertex_color_remove(struct wmOperatorType *ot); void MESH_OT_customdata_mask_clear(struct wmOperatorType *ot); void MESH_OT_customdata_skin_add(struct wmOperatorType *ot); void MESH_OT_customdata_skin_clear(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index be7f60b0da0..b9e78740e3c 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -134,10 +134,6 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_uv_texture_add); WM_operatortype_append(MESH_OT_uv_texture_remove); - WM_operatortype_append(MESH_OT_vertex_color_add); - WM_operatortype_append(MESH_OT_vertex_color_remove); - WM_operatortype_append(MESH_OT_sculpt_vertex_color_add); - WM_operatortype_append(MESH_OT_sculpt_vertex_color_remove); WM_operatortype_append(MESH_OT_customdata_mask_clear); WM_operatortype_append(MESH_OT_customdata_skin_add); WM_operatortype_append(MESH_OT_customdata_skin_clear); diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index 06a649e5b6c..6a5d620b546 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -744,7 +744,7 @@ Base *ED_mball_base_and_elem_from_select_buffer(Base **bases, const uint hit_object = select_id & 0xFFFF; Base *base = NULL; MetaElem *ml = NULL; - /* TODO(campbell): optimize, eg: sort & binary search. */ + /* TODO(@campbellbarton): optimize, eg: sort & binary search. */ for (uint base_index = 0; base_index < bases_len; base_index++) { if (bases[base_index]->object->runtime.select_id == hit_object) { base = bases[base_index]; diff --git a/source/blender/editors/object/object_remesh.cc b/source/blender/editors/object/object_remesh.cc index d44af45a015..ac4fb40d832 100644 --- a/source/blender/editors/object/object_remesh.cc +++ b/source/blender/editors/object/object_remesh.cc @@ -582,7 +582,7 @@ static int voxel_size_edit_invoke(bContext *C, wmOperator *op, const wmEvent *ev mat4_to_size(scale, active_object->obmat); invert_v3(scale); size_to_mat4(scale_mat, scale); - + mul_m4_m4_pre(cd->text_mat, scale_mat); /* Write the text position into the matrix. */ diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index c3d8fb9cfe5..6f7fc2efa61 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -1128,7 +1128,7 @@ static int object_select_all_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } if (any_visible == false) { - /* TODO(campbell): Looks like we could remove this, + /* TODO(@campbellbarton): Looks like we could remove this, * if not comment should say why its needed. */ return OPERATOR_PASS_THROUGH; } diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 17b7fe7fe5e..6369afac632 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -891,7 +891,7 @@ void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum) * deform group. */ - /* TODO(campbell): This is slow in a loop, better pass def_nr directly, + /* TODO(@campbellbarton): This is slow in a loop, better pass def_nr directly, * but leave for later. */ const ListBase *defbase = BKE_object_defgroup_list(ob); const int def_nr = BLI_findindex(defbase, dg); @@ -1118,7 +1118,7 @@ static void vgroup_duplicate(Object *ob) BKE_object_defgroup_active_index_set(ob, BLI_listbase_count(defbase)); icdg = BKE_object_defgroup_active_index_get(ob) - 1; - /* TODO(campbell): we might want to allow only copy selected verts here? */ + /* TODO(@campbellbarton): we might want to allow only copy selected verts here? */ ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false); if (dvert_array) { diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index e8ceb97ed7a..1ce90849a88 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -21,6 +21,7 @@ #include "DNA_object_types.h" #include "DNA_scene_types.h" +#include "BKE_attribute.h" #include "BKE_context.h" #include "BKE_deform.h" #include "BKE_dynamicpaint.h" @@ -233,7 +234,7 @@ static int output_toggle_exec(bContext *C, wmOperator *op) ED_mesh_color_add(ob->data, name, true, true, op->reports); } else { - ED_mesh_color_remove_named(ob->data, name); + BKE_id_attribute_remove(ob->data, name, NULL); } } /* Vertex Weight Layer */ diff --git a/source/blender/editors/render/render_opengl.cc b/source/blender/editors/render/render_opengl.cc index 77ad23f1e3f..e91bffce2c2 100644 --- a/source/blender/editors/render/render_opengl.cc +++ b/source/blender/editors/render/render_opengl.cc @@ -278,19 +278,10 @@ static void screen_opengl_views_setup(OGLRender *oglrender) static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, RenderResult *rr) { - Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Scene *scene = oglrender->scene; - ARegion *region = oglrender->region; - View3D *v3d = oglrender->v3d; - RegionView3D *rv3d = oglrender->rv3d; Object *camera = nullptr; int sizex = oglrender->sizex; int sizey = oglrender->sizey; - const short view_context = (v3d != nullptr); - bool draw_sky = (scene->r.alphamode == R_ADDSKY); - float *rectf = nullptr; - uchar *rect = nullptr; - const char *viewname = RE_GetActiveRenderView(oglrender->re); ImBuf *ibuf_result = nullptr; if (oglrender->is_sequencer) { @@ -301,7 +292,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R ImBuf *ibuf = oglrender->seq_data.ibufs_arr[oglrender->view_id]; if (ibuf) { - ImBuf *out = IMB_dupImBuf(ibuf); + ibuf_result = IMB_dupImBuf(ibuf); IMB_freeImBuf(ibuf); /* OpenGL render is considered to be preview and should be * as fast as possible. So currently we're making sure sequencer @@ -310,25 +301,21 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R * TODO(sergey): In the case of output to float container (EXR) * it actually makes sense to keep float buffer instead. */ - if (out->rect_float != nullptr) { - IMB_rect_from_float(out); - imb_freerectfloatImBuf(out); + if (ibuf_result->rect_float != nullptr) { + IMB_rect_from_float(ibuf_result); + imb_freerectfloatImBuf(ibuf_result); } - BLI_assert((oglrender->sizex == ibuf->x) && (oglrender->sizey == ibuf->y)); - RE_render_result_rect_from_ibuf(rr, out, oglrender->view_id); - IMB_freeImBuf(out); + BLI_assert((sizex == ibuf->x) && (sizey == ibuf->y)); } else if (gpd) { /* If there are no strips, Grease Pencil still needs a buffer to draw on */ - ImBuf *out = IMB_allocImBuf(oglrender->sizex, oglrender->sizey, 32, IB_rect); - RE_render_result_rect_from_ibuf(rr, out, oglrender->view_id); - IMB_freeImBuf(out); + ibuf_result = IMB_allocImBuf(sizex, sizey, 32, IB_rect); } if (gpd) { int i; uchar *gp_rect; - uchar *render_rect = (uchar *)RE_RenderViewGetById(rr, oglrender->view_id)->rect32; + uchar *render_rect = (uchar *)ibuf_result->rect; DRW_opengl_context_enable(); GPU_offscreen_bind(oglrender->ofs, true); @@ -359,10 +346,16 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R } else { /* shouldn't suddenly give errors mid-render but possible */ + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); char err_out[256] = "unknown"; ImBuf *ibuf_view; + bool draw_sky = (scene->r.alphamode == R_ADDSKY); const int alpha_mode = (draw_sky) ? R_ADDSKY : R_ALPHAPREMUL; - if (view_context) { + const char *viewname = RE_GetActiveRenderView(oglrender->re); + View3D *v3d = oglrender->v3d; + + if (v3d != nullptr) { + ARegion *region = oglrender->region; ibuf_view = ED_view3d_draw_offscreen_imbuf(depsgraph, scene, static_cast<eDrawType>(v3d->shading.type), @@ -378,7 +371,7 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R err_out); /* for stamp only */ - if (rv3d->persp == RV3D_CAMOB && v3d->camera) { + if (oglrender->rv3d->persp == RV3D_CAMOB && v3d->camera) { camera = BKE_camera_multiview_render(oglrender->scene, v3d->camera, viewname); } } @@ -388,8 +381,8 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R nullptr, OB_SOLID, scene->camera, - oglrender->sizex, - oglrender->sizey, + sizex, + sizey, IB_rectfloat, V3D_OFSDRAW_SHOW_ANNOTATION, alpha_mode, @@ -401,12 +394,6 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R if (ibuf_view) { ibuf_result = ibuf_view; - if (ibuf_view->rect_float) { - rectf = ibuf_view->rect_float; - } - else { - rect = (uchar *)ibuf_view->rect; - } } else { fprintf(stderr, "%s: failed to get buffer, %s\n", __func__, err_out); @@ -415,6 +402,14 @@ static void screen_opengl_render_doit(const bContext *C, OGLRender *oglrender, R if (ibuf_result != nullptr) { if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) { + float *rectf = nullptr; + uchar *rect = nullptr; + if (ibuf_result->rect_float) { + rectf = ibuf_result->rect_float; + } + else { + rect = (uchar *)ibuf_result->rect; + } BKE_image_stamp_buf(scene, camera, nullptr, rect, rectf, rr->rectx, rr->recty, 4); } RE_render_result_rect_from_ibuf(rr, ibuf_result, oglrender->view_id); diff --git a/source/blender/editors/render/render_preview.cc b/source/blender/editors/render/render_preview.cc index 97bbcaa102f..cd0a05f02bc 100644 --- a/source/blender/editors/render/render_preview.cc +++ b/source/blender/editors/render/render_preview.cc @@ -1771,7 +1771,7 @@ PreviewLoadJob &PreviewLoadJob::ensure_job(wmWindowManager *wm, wmWindow *win) WM_jobs_start(wm, wm_job); } - return *reinterpret_cast<PreviewLoadJob *>(WM_jobs_customdata_get(wm_job)); + return *static_cast<PreviewLoadJob *>(WM_jobs_customdata_get(wm_job)); } void PreviewLoadJob::load_jobless(PreviewImage *preview, const eIconSizes icon_size) @@ -1807,11 +1807,11 @@ void PreviewLoadJob::run_fn(void *customdata, short *do_update, float *UNUSED(progress)) { - PreviewLoadJob *job_data = reinterpret_cast<PreviewLoadJob *>(customdata); + PreviewLoadJob *job_data = static_cast<PreviewLoadJob *>(customdata); IMB_thumb_locks_acquire(); - while (RequestedPreview *request = reinterpret_cast<RequestedPreview *>( + while (RequestedPreview *request = static_cast<RequestedPreview *>( BLI_thread_queue_pop_timeout(job_data->todo_queue_, 100))) { if (*stop) { break; @@ -1864,7 +1864,7 @@ void PreviewLoadJob::finish_request(RequestedPreview &request) void PreviewLoadJob::update_fn(void *customdata) { - PreviewLoadJob *job_data = reinterpret_cast<PreviewLoadJob *>(customdata); + PreviewLoadJob *job_data = static_cast<PreviewLoadJob *>(customdata); for (auto request_it = job_data->requested_previews_.begin(); request_it != job_data->requested_previews_.end();) { @@ -1884,7 +1884,7 @@ void PreviewLoadJob::update_fn(void *customdata) void PreviewLoadJob::end_fn(void *customdata) { - PreviewLoadJob *job_data = reinterpret_cast<PreviewLoadJob *>(customdata); + PreviewLoadJob *job_data = static_cast<PreviewLoadJob *>(customdata); /* Finish any possibly remaining queued previews. */ for (RequestedPreview &request : job_data->requested_previews_) { @@ -1895,7 +1895,7 @@ void PreviewLoadJob::end_fn(void *customdata) void PreviewLoadJob::free_fn(void *customdata) { - MEM_delete(reinterpret_cast<PreviewLoadJob *>(customdata)); + MEM_delete(static_cast<PreviewLoadJob *>(customdata)); } static void icon_preview_free(void *customdata) diff --git a/source/blender/editors/render/render_update.cc b/source/blender/editors/render/render_update.cc index 3d26e764211..7cefcf9815e 100644 --- a/source/blender/editors/render/render_update.cc +++ b/source/blender/editors/render/render_update.cc @@ -95,20 +95,20 @@ void ED_render_view3d_update(Depsgraph *depsgraph, CTX_free(C); } - else { - RenderEngineType *engine_type = ED_view3d_engine_type(scene, v3d->shading.type); - if (updated) { - DRWUpdateContext drw_context = {nullptr}; - drw_context.bmain = bmain; - drw_context.depsgraph = depsgraph; - drw_context.scene = scene; - drw_context.view_layer = view_layer; - drw_context.region = region; - drw_context.v3d = v3d; - drw_context.engine_type = engine_type; - DRW_notify_view_update(&drw_context); - } + + if (!updated) { + continue; } + + DRWUpdateContext drw_context = {nullptr}; + drw_context.bmain = bmain; + drw_context.depsgraph = depsgraph; + drw_context.scene = scene; + drw_context.view_layer = view_layer; + drw_context.region = region; + drw_context.v3d = v3d; + drw_context.engine_type = ED_view3d_engine_type(scene, v3d->shading.type); + DRW_notify_view_update(&drw_context); } } diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c index 0d6b6ee1d78..83e6c837eac 100644 --- a/source/blender/editors/screen/screen_context.c +++ b/source/blender/editors/screen/screen_context.c @@ -1032,15 +1032,13 @@ static eContextResult screen_ctx_sel_actions_impl(const bContext *C, CTX_data_id_pointer_set(result, (ID *)action); break; } - else { - if (editable && ID_IS_LINKED(action)) { - continue; - } + if (editable && ID_IS_LINKED(action)) { + continue; + } - /* Add the action to the output list if not already added. */ - if (BLI_gset_add(seen_set, action)) { - CTX_data_id_list_add(result, &action->id); - } + /* Add the action to the output list if not already added. */ + if (BLI_gset_add(seen_set, action)) { + CTX_data_id_list_add(result, &action->id); } } } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index 08c8c863729..73195168d38 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -110,7 +110,7 @@ ScrArea *area_split(const wmWindow *win, return NULL; } - /* NOTE(campbell): regarding (fac > 0.5f) checks below. + /* NOTE(@campbellbarton): regarding (fac > 0.5f) checks below. * normally it shouldn't matter which is used since the copy should match the original * however with viewport rendering and python console this isn't the case. */ diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c index cb29f15420c..fc3ac53ef0b 100644 --- a/source/blender/editors/screen/workspace_edit.c +++ b/source/blender/editors/screen/workspace_edit.c @@ -220,7 +220,7 @@ WorkSpace *ED_workspace_duplicate(WorkSpace *workspace_old, Main *bmain, wmWindo workspace_new->order = workspace_old->order; BLI_duplicatelist(&workspace_new->owner_ids, &workspace_old->owner_ids); - /* TODO(campbell): tools */ + /* TODO(@campbellbarton): tools */ LISTBASE_FOREACH (WorkSpaceLayout *, layout_old, &workspace_old->layouts) { WorkSpaceLayout *layout_new = ED_workspace_layout_duplicate( diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index edb0f1cda4d..b170280ccf3 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -37,8 +37,8 @@ set(SRC curves_sculpt_ops.cc curves_sculpt_pinch.cc curves_sculpt_puff.cc - curves_sculpt_selection_paint.cc curves_sculpt_selection.cc + curves_sculpt_selection_paint.cc curves_sculpt_slide.cc curves_sculpt_smooth.cc curves_sculpt_snake_hook.cc diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc index 5bfc8ccc667..a955a074df2 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_selection.cc @@ -67,10 +67,11 @@ static IndexMask retrieve_selected_curves(const CurvesGeometry &curves, return selection.get_internal_single() <= 0.0f ? IndexMask(0) : IndexMask(curves.curves_num()); } + const Span<float> point_selection_span = selection.get_internal_span(); return index_mask_ops::find_indices_based_on_predicate( curves.curves_range(), 512, r_indices, [&](const int curve_i) { for (const int i : curves.points_for_curve(curve_i)) { - if (selection[i] > 0.0f) { + if (point_selection_span[i] > 0.0f) { return true; } } diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index c5ebcf870a3..577540725af 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -1145,11 +1145,10 @@ static void sculpt_geometry_preview_lines_draw(const uint gpuattr, } GPU_line_width(1.0f); - if (ss->preview_vert_index_count > 0) { - immBegin(GPU_PRIM_LINES, ss->preview_vert_index_count); - for (int i = 0; i < ss->preview_vert_index_count; i++) { - immVertex3fv(gpuattr, - SCULPT_vertex_co_for_grab_active_get(ss, ss->preview_vert_index_list[i])); + if (ss->preview_vert_count > 0) { + immBegin(GPU_PRIM_LINES, ss->preview_vert_count); + for (int i = 0; i < ss->preview_vert_count; i++) { + immVertex3fv(gpuattr, SCULPT_vertex_co_for_grab_active_get(ss, ss->preview_vert_list[i])); } immEnd(); } @@ -1209,7 +1208,7 @@ typedef struct PaintCursorContext { /* Sculpt related data. */ Sculpt *sd; SculptSession *ss; - int prev_active_vertex_index; + PBVHVertRef prev_active_vertex; bool is_stroke_active; bool is_cursor_over_mesh; bool is_multires; @@ -1366,7 +1365,7 @@ static void paint_cursor_sculpt_session_update_and_init(PaintCursorContext *pcon /* This updates the active vertex, which is needed for most of the Sculpt/Vertex Colors tools to * work correctly */ - pcontext->prev_active_vertex_index = ss->active_vertex_index; + pcontext->prev_active_vertex = ss->active_vertex; if (!ups->stroke_active) { pcontext->is_cursor_over_mesh = SCULPT_cursor_geometry_info_update( C, &gi, mval_fl, (pcontext->brush->falloff_shape == PAINT_FALLOFF_SHAPE_SPHERE)); @@ -1549,7 +1548,7 @@ static void paint_cursor_preview_boundary_data_update(PaintCursorContext *pconte } ss->boundary_preview = SCULPT_boundary_data_init( - pcontext->vc.obact, pcontext->brush, ss->active_vertex_index, pcontext->radius); + pcontext->vc.obact, pcontext->brush, ss->active_vertex, pcontext->radius); } static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext *pcontext) @@ -1575,8 +1574,8 @@ static void paint_cursor_draw_3d_view_brush_cursor_inactive(PaintCursorContext * paint_cursor_update_object_space_radius(pcontext); - const bool update_previews = pcontext->prev_active_vertex_index != - SCULPT_active_vertex_get(pcontext->ss); + const bool update_previews = pcontext->prev_active_vertex.i != + SCULPT_active_vertex_get(pcontext->ss).i; /* Setup drawing. */ wmViewport(&pcontext->region->winrct); diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 9449cc6eb8d..3e5ad9bdc2d 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -1223,12 +1223,12 @@ static VertSeam *find_adjacent_seam(const ProjPaintState *ps, /* Circulate through the (sorted) vert seam array, in the direction of the seam normal, * until we find the first opposing seam, matching in UV space. */ if (seam->normal_cw) { - LISTBASE_CIRCULAR_BACKWARD_BEGIN (vert_seams, adjacent, seam) { + LISTBASE_CIRCULAR_BACKWARD_BEGIN (VertSeam *, vert_seams, adjacent, seam) { if ((adjacent->normal_cw != seam->normal_cw) && cmp_uv(adjacent->uv, seam->uv)) { break; } } - LISTBASE_CIRCULAR_BACKWARD_END(vert_seams, adjacent, seam); + LISTBASE_CIRCULAR_BACKWARD_END(VertSeam *, vert_seams, adjacent, seam); } else { LISTBASE_CIRCULAR_FORWARD_BEGIN (vert_seams, adjacent, seam) { diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index b861d0c84da..2e57886fd95 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -663,7 +663,7 @@ static bool sculpt_gesture_is_effected_lasso(SculptGestureContext *sgcontext, co static bool sculpt_gesture_is_vertex_effected(SculptGestureContext *sgcontext, PBVHVertexIter *vd) { float vertex_normal[3]; - SCULPT_vertex_normal_get(sgcontext->ss, vd->index, vertex_normal); + SCULPT_vertex_normal_get(sgcontext->ss, vd->vertex, vertex_normal); float dot = dot_v3v3(sgcontext->view_normal, vertex_normal); const bool is_effected_front_face = !(sgcontext->front_faces_only && dot < 0.0f); @@ -743,7 +743,7 @@ static void face_set_gesture_apply_task_cb(void *__restrict userdata, BKE_pbvh_vertex_iter_begin (sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) { - SCULPT_vertex_face_set_set(sgcontext->ss, vd.index, face_set_operation->new_face_set_id); + SCULPT_vertex_face_set_set(sgcontext->ss, vd.vertex, face_set_operation->new_face_set_id); any_updated = true; } } @@ -1025,7 +1025,9 @@ static void sculpt_gesture_trim_calculate_depth(SculptGestureContext *sgcontext) trim_operation->depth_back = -FLT_MAX; for (int i = 0; i < totvert; i++) { - const float *vco = SCULPT_vertex_co_get(ss, i); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + const float *vco = SCULPT_vertex_co_get(ss, vertex); /* Convert the coordinates to world space to calculate the depth. When generating the trimming * mesh, coordinates are first calculated in world space, then converted to object space to * store them. */ @@ -1437,7 +1439,7 @@ static void project_line_gesture_apply_task_cb(void *__restrict userdata, } add_v3_v3(vd.co, disp); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(sgcontext->ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(sgcontext->ss->pbvh, vd.vertex); } any_updated = true; } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index aa151b2e678..02d21941a25 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -122,22 +122,22 @@ int SCULPT_vertex_count_get(SculptSession *ss) return 0; } -const float *SCULPT_vertex_co_get(SculptSession *ss, int index) +const float *SCULPT_vertex_co_get(SculptSession *ss, PBVHVertRef vertex) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { if (ss->shapekey_active || ss->deform_modifiers_active) { const MVert *mverts = BKE_pbvh_get_verts(ss->pbvh); - return mverts[index].co; + return mverts[vertex.i].co; } - return ss->mvert[index].co; + return ss->mvert[vertex.i].co; } case PBVH_BMESH: - return BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->co; + return ((BMVert *)vertex.i)->co; case PBVH_GRIDS: { const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); - const int grid_index = index / key->grid_area; - const int vertex_index = index - grid_index * key->grid_area; + const int grid_index = vertex.i / key->grid_area; + const int vertex_index = vertex.i - grid_index * key->grid_area; CCGElem *elem = BKE_pbvh_get_grids(ss->pbvh)[grid_index]; return CCG_elem_co(key, CCG_elem_offset(key, elem, vertex_index)); } @@ -158,31 +158,33 @@ bool SCULPT_has_colors(const SculptSession *ss) return ss->vcol || ss->mcol; } -void SCULPT_vertex_color_get(const SculptSession *ss, int index, float r_color[4]) +void SCULPT_vertex_color_get(const SculptSession *ss, PBVHVertRef vertex, float r_color[4]) { - BKE_pbvh_vertex_color_get(ss->pbvh, index, r_color); + BKE_pbvh_vertex_color_get(ss->pbvh, vertex, r_color); } -void SCULPT_vertex_color_set(SculptSession *ss, int index, const float color[4]) +void SCULPT_vertex_color_set(SculptSession *ss, PBVHVertRef vertex, const float color[4]) { - BKE_pbvh_vertex_color_set(ss->pbvh, index, color); + BKE_pbvh_vertex_color_set(ss->pbvh, vertex, color); } -void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3]) +void SCULPT_vertex_normal_get(SculptSession *ss, PBVHVertRef vertex, float no[3]) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { const float(*vert_normals)[3] = BKE_pbvh_get_vert_normals(ss->pbvh); - copy_v3_v3(no, vert_normals[index]); + copy_v3_v3(no, vert_normals[vertex.i]); break; } - case PBVH_BMESH: - copy_v3_v3(no, BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index)->no); + case PBVH_BMESH: { + BMVert *v = (BMVert *)vertex.i; + copy_v3_v3(no, v->no); break; + } case PBVH_GRIDS: { const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); - const int grid_index = index / key->grid_area; - const int vertex_index = index - grid_index * key->grid_area; + const int grid_index = vertex.i / key->grid_area; + const int vertex_index = vertex.i - grid_index * key->grid_area; CCGElem *elem = BKE_pbvh_get_grids(ss->pbvh)[grid_index]; copy_v3_v3(no, CCG_elem_no(key, CCG_elem_offset(key, elem, vertex_index))); break; @@ -190,42 +192,42 @@ void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3]) } } -const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index) +const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, PBVHVertRef vertex) { if (ss->persistent_base) { - return ss->persistent_base[index].co; + return ss->persistent_base[BKE_pbvh_vertex_to_index(ss->pbvh, vertex)].co; } - return SCULPT_vertex_co_get(ss, index); + return SCULPT_vertex_co_get(ss, vertex); } -const float *SCULPT_vertex_co_for_grab_active_get(SculptSession *ss, int index) +const float *SCULPT_vertex_co_for_grab_active_get(SculptSession *ss, PBVHVertRef vertex) { - /* Always grab active shape key if the sculpt happens on shapekey. */ - if (ss->shapekey_active) { - const MVert *mverts = BKE_pbvh_get_verts(ss->pbvh); - return mverts[index].co; - } + if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) { + /* Always grab active shape key if the sculpt happens on shapekey. */ + if (ss->shapekey_active) { + const MVert *mverts = BKE_pbvh_get_verts(ss->pbvh); + return mverts[vertex.i].co; + } - /* Sculpting on the base mesh. */ - if (ss->mvert) { - return ss->mvert[index].co; + /* Sculpting on the base mesh. */ + return ss->mvert[vertex.i].co; } /* Everything else, such as sculpting on multires. */ - return SCULPT_vertex_co_get(ss, index); + return SCULPT_vertex_co_get(ss, vertex); } -void SCULPT_vertex_limit_surface_get(SculptSession *ss, int index, float r_co[3]) +void SCULPT_vertex_limit_surface_get(SculptSession *ss, PBVHVertRef vertex, float r_co[3]) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: case PBVH_BMESH: - copy_v3_v3(r_co, SCULPT_vertex_co_get(ss, index)); + copy_v3_v3(r_co, SCULPT_vertex_co_get(ss, vertex)); break; case PBVH_GRIDS: { const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); - const int grid_index = index / key->grid_area; - const int vertex_index = index - grid_index * key->grid_area; + const int grid_index = vertex.i / key->grid_area; + const int vertex_index = vertex.i - grid_index * key->grid_area; SubdivCCGCoord coord = {.grid_index = grid_index, .x = vertex_index % key->grid_size, @@ -236,30 +238,30 @@ void SCULPT_vertex_limit_surface_get(SculptSession *ss, int index, float r_co[3] } } -void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3]) +void SCULPT_vertex_persistent_normal_get(SculptSession *ss, PBVHVertRef vertex, float no[3]) { if (ss->persistent_base) { - copy_v3_v3(no, ss->persistent_base[index].no); + copy_v3_v3(no, ss->persistent_base[vertex.i].no); return; } - SCULPT_vertex_normal_get(ss, index, no); + SCULPT_vertex_normal_get(ss, vertex, no); } -float SCULPT_vertex_mask_get(SculptSession *ss, int index) +float SCULPT_vertex_mask_get(SculptSession *ss, PBVHVertRef vertex) { BMVert *v; float *mask; switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: - return ss->vmask[index]; + return ss->vmask[vertex.i]; case PBVH_BMESH: - v = BM_vert_at_index(BKE_pbvh_get_bmesh(ss->pbvh), index); + v = (BMVert *)vertex.i; mask = BM_ELEM_CD_GET_VOID_P(v, CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK)); return *mask; case PBVH_GRIDS: { const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); - const int grid_index = index / key->grid_area; - const int vertex_index = index - grid_index * key->grid_area; + const int grid_index = vertex.i / key->grid_area; + const int vertex_index = vertex.i - grid_index * key->grid_area; CCGElem *elem = BKE_pbvh_get_grids(ss->pbvh)[grid_index]; return *CCG_elem_mask(key, CCG_elem_offset(key, elem, vertex_index)); } @@ -268,12 +270,13 @@ float SCULPT_vertex_mask_get(SculptSession *ss, int index) return 0.0f; } -int SCULPT_active_vertex_get(SculptSession *ss) +PBVHVertRef SCULPT_active_vertex_get(SculptSession *ss) { if (ELEM(BKE_pbvh_type(ss->pbvh), PBVH_FACES, PBVH_BMESH, PBVH_GRIDS)) { - return ss->active_vertex_index; + return ss->active_vertex; } - return 0; + + return BKE_pbvh_make_vref(PBVH_REF_NONE); } const float *SCULPT_active_vertex_co_get(SculptSession *ss) @@ -338,32 +341,33 @@ int SCULPT_active_face_set_get(SculptSession *ss) return SCULPT_FACE_SET_NONE; } -void SCULPT_vertex_visible_set(SculptSession *ss, int index, bool visible) +void SCULPT_vertex_visible_set(SculptSession *ss, PBVHVertRef vertex, bool visible) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: - SET_FLAG_FROM_TEST(ss->mvert[index].flag, !visible, ME_HIDE); - BKE_pbvh_vert_tag_update_normal(ss->pbvh, index); + SET_FLAG_FROM_TEST(ss->mvert[vertex.i].flag, !visible, ME_HIDE); break; - case PBVH_BMESH: - BM_elem_flag_set(BM_vert_at_index(ss->bm, index), BM_ELEM_HIDDEN, !visible); + case PBVH_BMESH: { + BMVert *v = (BMVert *)vertex.i; + BM_elem_flag_set(v, BM_ELEM_HIDDEN, !visible); break; + } case PBVH_GRIDS: break; } } -bool SCULPT_vertex_visible_get(SculptSession *ss, int index) +bool SCULPT_vertex_visible_get(SculptSession *ss, PBVHVertRef vertex) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: - return !(ss->mvert[index].flag & ME_HIDE); + return !(ss->mvert[vertex.i].flag & ME_HIDE); case PBVH_BMESH: - return !BM_elem_flag_test(BM_vert_at_index(ss->bm, index), BM_ELEM_HIDDEN); + return !BM_elem_flag_test((BMVert *)vertex.i, BM_ELEM_HIDDEN); case PBVH_GRIDS: { const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); - const int grid_index = index / key->grid_area; - const int vertex_index = index - grid_index * key->grid_area; + const int grid_index = vertex.i / key->grid_area; + const int vertex_index = vertex.i - grid_index * key->grid_area; BLI_bitmap **grid_hidden = BKE_pbvh_get_grid_visibility(ss->pbvh); if (grid_hidden && grid_hidden[grid_index]) { return !BLI_BITMAP_TEST(grid_hidden[grid_index], vertex_index); @@ -436,12 +440,12 @@ void SCULPT_face_sets_visibility_all_set(SculptSession *ss, bool visible) } } -bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, int index) +bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, PBVHVertRef vertex) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { - MeshElemMap *vert_map = &ss->pmap[index]; - for (int j = 0; j < ss->pmap[index].count; j++) { + MeshElemMap *vert_map = &ss->pmap[vertex.i]; + for (int j = 0; j < ss->pmap[vertex.i].count; j++) { if (ss->face_sets[vert_map->indices[j]] > 0) { return true; } @@ -456,12 +460,12 @@ bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, int index) return true; } -bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, int index) +bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, PBVHVertRef vertex) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { - MeshElemMap *vert_map = &ss->pmap[index]; - for (int j = 0; j < ss->pmap[index].count; j++) { + MeshElemMap *vert_map = &ss->pmap[vertex.i]; + for (int j = 0; j < ss->pmap[vertex.i].count; j++) { if (ss->face_sets[vert_map->indices[j]] < 0) { return false; } @@ -472,7 +476,7 @@ bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, int index) return true; case PBVH_GRIDS: { const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); - const int grid_index = index / key->grid_area; + const int grid_index = vertex.i / key->grid_area; const int face_index = BKE_subdiv_ccg_grid_to_face_index(ss->subdiv_ccg, grid_index); return ss->face_sets[face_index] > 0; } @@ -480,12 +484,12 @@ bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, int index) return true; } -void SCULPT_vertex_face_set_set(SculptSession *ss, int index, int face_set) +void SCULPT_vertex_face_set_set(SculptSession *ss, PBVHVertRef vertex, int face_set) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { - MeshElemMap *vert_map = &ss->pmap[index]; - for (int j = 0; j < ss->pmap[index].count; j++) { + MeshElemMap *vert_map = &ss->pmap[vertex.i]; + for (int j = 0; j < ss->pmap[vertex.i].count; j++) { if (ss->face_sets[vert_map->indices[j]] > 0) { ss->face_sets[vert_map->indices[j]] = abs(face_set); } @@ -495,7 +499,7 @@ void SCULPT_vertex_face_set_set(SculptSession *ss, int index, int face_set) break; case PBVH_GRIDS: { const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); - const int grid_index = index / key->grid_area; + const int grid_index = vertex.i / key->grid_area; const int face_index = BKE_subdiv_ccg_grid_to_face_index(ss->subdiv_ccg, grid_index); if (ss->face_sets[face_index] > 0) { ss->face_sets[face_index] = abs(face_set); @@ -505,13 +509,13 @@ void SCULPT_vertex_face_set_set(SculptSession *ss, int index, int face_set) } } -int SCULPT_vertex_face_set_get(SculptSession *ss, int index) +int SCULPT_vertex_face_set_get(SculptSession *ss, PBVHVertRef vertex) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { - MeshElemMap *vert_map = &ss->pmap[index]; + MeshElemMap *vert_map = &ss->pmap[vertex.i]; int face_set = 0; - for (int i = 0; i < ss->pmap[index].count; i++) { + for (int i = 0; i < ss->pmap[vertex.i].count; i++) { if (ss->face_sets[vert_map->indices[i]] > face_set) { face_set = abs(ss->face_sets[vert_map->indices[i]]); } @@ -522,7 +526,7 @@ int SCULPT_vertex_face_set_get(SculptSession *ss, int index) return 0; case PBVH_GRIDS: { const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); - const int grid_index = index / key->grid_area; + const int grid_index = vertex.i / key->grid_area; const int face_index = BKE_subdiv_ccg_grid_to_face_index(ss->subdiv_ccg, grid_index); return ss->face_sets[face_index]; } @@ -530,12 +534,12 @@ int SCULPT_vertex_face_set_get(SculptSession *ss, int index) return 0; } -bool SCULPT_vertex_has_face_set(SculptSession *ss, int index, int face_set) +bool SCULPT_vertex_has_face_set(SculptSession *ss, PBVHVertRef vertex, int face_set) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { - MeshElemMap *vert_map = &ss->pmap[index]; - for (int i = 0; i < ss->pmap[index].count; i++) { + MeshElemMap *vert_map = &ss->pmap[vertex.i]; + for (int i = 0; i < ss->pmap[vertex.i].count; i++) { if (ss->face_sets[vert_map->indices[i]] == face_set) { return true; } @@ -546,7 +550,7 @@ bool SCULPT_vertex_has_face_set(SculptSession *ss, int index, int face_set) return true; case PBVH_GRIDS: { const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); - const int grid_index = index / key->grid_area; + const int grid_index = vertex.i / key->grid_area; const int face_index = BKE_subdiv_ccg_grid_to_face_index(ss->subdiv_ccg, grid_index); return ss->face_sets[face_index] == face_set; } @@ -574,11 +578,11 @@ void SCULPT_visibility_sync_all_face_sets_to_vertices(Object *ob) } static void UNUSED_FUNCTION(sculpt_visibility_sync_vertex_to_face_sets)(SculptSession *ss, - int index) + PBVHVertRef vertex) { - MeshElemMap *vert_map = &ss->pmap[index]; - const bool visible = SCULPT_vertex_visible_get(ss, index); - for (int i = 0; i < ss->pmap[index].count; i++) { + MeshElemMap *vert_map = &ss->pmap[vertex.i]; + const bool visible = SCULPT_vertex_visible_get(ss, vertex); + for (int i = 0; i < ss->pmap[vertex.i].count; i++) { if (visible) { ss->face_sets[vert_map->indices[i]] = abs(ss->face_sets[vert_map->indices[i]]); } @@ -596,7 +600,7 @@ void SCULPT_visibility_sync_all_vertex_to_face_sets(SculptSession *ss) bool poly_visible = true; for (int l = 0; l < poly->totloop; l++) { MLoop *loop = &ss->mloop[poly->loopstart + l]; - if (!SCULPT_vertex_visible_get(ss, (int)loop->v)) { + if (!SCULPT_vertex_visible_get(ss, BKE_pbvh_make_vref(loop->v))) { poly_visible = false; } } @@ -659,18 +663,18 @@ static bool sculpt_check_unique_face_set_for_edge_in_base_mesh(SculptSession *ss return true; } -bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, int index) +bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, PBVHVertRef vertex) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { - return sculpt_check_unique_face_set_in_base_mesh(ss, index); + return sculpt_check_unique_face_set_in_base_mesh(ss, vertex.i); } case PBVH_BMESH: return true; case PBVH_GRIDS: { const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); - const int grid_index = index / key->grid_area; - const int vertex_index = index - grid_index * key->grid_area; + const int grid_index = vertex.i / key->grid_area; + const int vertex_index = vertex.i - grid_index * key->grid_area; const SubdivCCGCoord coord = {.grid_index = grid_index, .x = vertex_index % key->grid_size, .y = vertex_index / key->grid_size}; @@ -714,10 +718,12 @@ int SCULPT_face_set_next_available_get(SculptSession *ss) #define SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY 256 -static void sculpt_vertex_neighbor_add(SculptVertexNeighborIter *iter, int neighbor_index) +static void sculpt_vertex_neighbor_add(SculptVertexNeighborIter *iter, + PBVHVertRef neighbor, + int neighbor_index) { for (int i = 0; i < iter->size; i++) { - if (iter->neighbors[i] == neighbor_index) { + if (iter->neighbors[i].i == neighbor.i) { return; } } @@ -726,63 +732,74 @@ static void sculpt_vertex_neighbor_add(SculptVertexNeighborIter *iter, int neigh iter->capacity += SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY; if (iter->neighbors == iter->neighbors_fixed) { - iter->neighbors = MEM_mallocN(iter->capacity * sizeof(int), "neighbor array"); - memcpy(iter->neighbors, iter->neighbors_fixed, sizeof(int) * iter->size); + iter->neighbors = MEM_mallocN(iter->capacity * sizeof(PBVHVertRef), "neighbor array"); + memcpy(iter->neighbors, iter->neighbors_fixed, sizeof(PBVHVertRef) * iter->size); } else { iter->neighbors = MEM_reallocN_id( - iter->neighbors, iter->capacity * sizeof(int), "neighbor array"); + iter->neighbors, iter->capacity * sizeof(PBVHVertRef), "neighbor array"); + } + + if (iter->neighbor_indices == iter->neighbor_indices_fixed) { + iter->neighbor_indices = MEM_mallocN(iter->capacity * sizeof(int), "neighbor array"); + memcpy(iter->neighbor_indices, iter->neighbor_indices_fixed, sizeof(int) * iter->size); + } + else { + iter->neighbor_indices = MEM_reallocN_id( + iter->neighbor_indices, iter->capacity * sizeof(int), "neighbor array"); } } - iter->neighbors[iter->size] = neighbor_index; + iter->neighbors[iter->size] = neighbor; + iter->neighbor_indices[iter->size] = neighbor_index; iter->size++; } -static void sculpt_vertex_neighbors_get_bmesh(SculptSession *ss, - int index, - SculptVertexNeighborIter *iter) +static void sculpt_vertex_neighbors_get_bmesh(PBVHVertRef vertex, SculptVertexNeighborIter *iter) { - BMVert *v = BM_vert_at_index(ss->bm, index); + BMVert *v = (BMVert *)vertex.i; BMIter liter; BMLoop *l; iter->size = 0; iter->num_duplicates = 0; iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY; iter->neighbors = iter->neighbors_fixed; + iter->neighbor_indices = iter->neighbor_indices_fixed; BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) { const BMVert *adj_v[2] = {l->prev->v, l->next->v}; for (int i = 0; i < ARRAY_SIZE(adj_v); i++) { const BMVert *v_other = adj_v[i]; - if (BM_elem_index_get(v_other) != (int)index) { - sculpt_vertex_neighbor_add(iter, BM_elem_index_get(v_other)); + if (v_other != v) { + sculpt_vertex_neighbor_add( + iter, BKE_pbvh_make_vref((intptr_t)v_other), BM_elem_index_get(v_other)); } } } } static void sculpt_vertex_neighbors_get_faces(SculptSession *ss, - int index, + PBVHVertRef vertex, SculptVertexNeighborIter *iter) { - MeshElemMap *vert_map = &ss->pmap[index]; + MeshElemMap *vert_map = &ss->pmap[vertex.i]; iter->size = 0; iter->num_duplicates = 0; iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY; iter->neighbors = iter->neighbors_fixed; + iter->neighbor_indices = iter->neighbor_indices_fixed; - for (int i = 0; i < ss->pmap[index].count; i++) { + for (int i = 0; i < ss->pmap[vertex.i].count; i++) { if (ss->face_sets[vert_map->indices[i]] < 0) { /* Skip connectivity from hidden faces. */ continue; } const MPoly *p = &ss->mpoly[vert_map->indices[i]]; uint f_adj_v[2]; - if (poly_get_adj_loops_from_vert(p, ss->mloop, index, f_adj_v) != -1) { + if (poly_get_adj_loops_from_vert(p, ss->mloop, vertex.i, f_adj_v) != -1) { for (int j = 0; j < ARRAY_SIZE(f_adj_v); j += 1) { - if (f_adj_v[j] != index) { - sculpt_vertex_neighbor_add(iter, f_adj_v[j]); + if (f_adj_v[j] != vertex.i) { + sculpt_vertex_neighbor_add(iter, BKE_pbvh_make_vref(f_adj_v[j]), f_adj_v[j]); } } } @@ -790,14 +807,17 @@ static void sculpt_vertex_neighbors_get_faces(SculptSession *ss, if (ss->fake_neighbors.use_fake_neighbors) { BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL); - if (ss->fake_neighbors.fake_neighbor_index[index] != FAKE_NEIGHBOR_NONE) { - sculpt_vertex_neighbor_add(iter, ss->fake_neighbors.fake_neighbor_index[index]); + if (ss->fake_neighbors.fake_neighbor_index[vertex.i] != FAKE_NEIGHBOR_NONE) { + sculpt_vertex_neighbor_add( + iter, + BKE_pbvh_make_vref(ss->fake_neighbors.fake_neighbor_index[vertex.i]), + ss->fake_neighbors.fake_neighbor_index[vertex.i]); } } } static void sculpt_vertex_neighbors_get_grids(SculptSession *ss, - const int index, + const PBVHVertRef vertex, const bool include_duplicates, SculptVertexNeighborIter *iter) { @@ -805,8 +825,8 @@ static void sculpt_vertex_neighbors_get_grids(SculptSession *ss, * maybe provide coordinate and mask pointers directly rather than converting * back and forth between #CCGElem and global index. */ const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); - const int grid_index = index / key->grid_area; - const int vertex_index = index - grid_index * key->grid_area; + const int grid_index = vertex.i / key->grid_area; + const int vertex_index = vertex.i - grid_index * key->grid_area; SubdivCCGCoord coord = {.grid_index = grid_index, .x = vertex_index % key->grid_size, @@ -819,17 +839,20 @@ static void sculpt_vertex_neighbors_get_grids(SculptSession *ss, iter->num_duplicates = neighbors.num_duplicates; iter->capacity = SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY; iter->neighbors = iter->neighbors_fixed; + iter->neighbor_indices = iter->neighbor_indices_fixed; for (int i = 0; i < neighbors.size; i++) { - sculpt_vertex_neighbor_add(iter, - neighbors.coords[i].grid_index * key->grid_area + - neighbors.coords[i].y * key->grid_size + neighbors.coords[i].x); + int v = neighbors.coords[i].grid_index * key->grid_area + + neighbors.coords[i].y * key->grid_size + neighbors.coords[i].x; + + sculpt_vertex_neighbor_add(iter, BKE_pbvh_make_vref(v), v); } if (ss->fake_neighbors.use_fake_neighbors) { BLI_assert(ss->fake_neighbors.fake_neighbor_index != NULL); - if (ss->fake_neighbors.fake_neighbor_index[index] != FAKE_NEIGHBOR_NONE) { - sculpt_vertex_neighbor_add(iter, ss->fake_neighbors.fake_neighbor_index[index]); + if (ss->fake_neighbors.fake_neighbor_index[vertex.i] != FAKE_NEIGHBOR_NONE) { + int v = ss->fake_neighbors.fake_neighbor_index[vertex.i]; + sculpt_vertex_neighbor_add(iter, BKE_pbvh_make_vref(v), v); } } @@ -839,19 +862,19 @@ static void sculpt_vertex_neighbors_get_grids(SculptSession *ss, } void SCULPT_vertex_neighbors_get(SculptSession *ss, - const int index, + const PBVHVertRef vertex, const bool include_duplicates, SculptVertexNeighborIter *iter) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: - sculpt_vertex_neighbors_get_faces(ss, index, iter); + sculpt_vertex_neighbors_get_faces(ss, vertex, iter); return; case PBVH_BMESH: - sculpt_vertex_neighbors_get_bmesh(ss, index, iter); + sculpt_vertex_neighbors_get_bmesh(vertex, iter); return; case PBVH_GRIDS: - sculpt_vertex_neighbors_get_grids(ss, index, include_duplicates, iter); + sculpt_vertex_neighbors_get_grids(ss, vertex, include_duplicates, iter); return; } } @@ -862,24 +885,24 @@ static bool sculpt_check_boundary_vertex_in_base_mesh(const SculptSession *ss, c return BLI_BITMAP_TEST(ss->vertex_info.boundary, index); } -bool SCULPT_vertex_is_boundary(const SculptSession *ss, const int index) +bool SCULPT_vertex_is_boundary(const SculptSession *ss, const PBVHVertRef vertex) { switch (BKE_pbvh_type(ss->pbvh)) { case PBVH_FACES: { - if (!SCULPT_vertex_all_face_sets_visible_get(ss, index)) { + if (!SCULPT_vertex_all_face_sets_visible_get(ss, vertex)) { return true; } - return sculpt_check_boundary_vertex_in_base_mesh(ss, index); + return sculpt_check_boundary_vertex_in_base_mesh(ss, vertex.i); } case PBVH_BMESH: { - BMVert *v = BM_vert_at_index(ss->bm, index); + BMVert *v = (BMVert *)vertex.i; return BM_vert_is_boundary(v); } case PBVH_GRIDS: { const CCGKey *key = BKE_pbvh_get_grid_key(ss->pbvh); - const int grid_index = index / key->grid_area; - const int vertex_index = index - grid_index * key->grid_area; + const int grid_index = vertex.i / key->grid_area; + const int vertex_index = vertex.i - grid_index * key->grid_area; const SubdivCCGCoord coord = {.grid_index = grid_index, .x = vertex_index % key->grid_size, .y = vertex_index / key->grid_size}; @@ -940,7 +963,7 @@ bool SCULPT_check_vertex_pivot_symmetry(const float vco[3], const float pco[3], } typedef struct NearestVertexTLSData { - int nearest_vertex_index; + PBVHVertRef nearest_vertex; float nearest_vertex_distance_squared; } NearestVertexTLSData; @@ -957,7 +980,7 @@ static void do_nearest_vertex_get_task_cb(void *__restrict userdata, float distance_squared = len_squared_v3v3(vd.co, data->nearest_vertex_search_co); if (distance_squared < nvtd->nearest_vertex_distance_squared && distance_squared < data->max_distance_squared) { - nvtd->nearest_vertex_index = vd.index; + nvtd->nearest_vertex = vd.vertex; nvtd->nearest_vertex_distance_squared = distance_squared; } } @@ -970,17 +993,17 @@ static void nearest_vertex_get_reduce(const void *__restrict UNUSED(userdata), { NearestVertexTLSData *join = chunk_join; NearestVertexTLSData *nvtd = chunk; - if (join->nearest_vertex_index == -1) { - join->nearest_vertex_index = nvtd->nearest_vertex_index; + if (join->nearest_vertex.i == PBVH_REF_NONE) { + join->nearest_vertex = nvtd->nearest_vertex; join->nearest_vertex_distance_squared = nvtd->nearest_vertex_distance_squared; } else if (nvtd->nearest_vertex_distance_squared < join->nearest_vertex_distance_squared) { - join->nearest_vertex_index = nvtd->nearest_vertex_index; + join->nearest_vertex = nvtd->nearest_vertex; join->nearest_vertex_distance_squared = nvtd->nearest_vertex_distance_squared; } } -int SCULPT_nearest_vertex_get( +PBVHVertRef SCULPT_nearest_vertex_get( Sculpt *sd, Object *ob, const float co[3], float max_distance, bool use_original) { SculptSession *ss = ob->sculpt; @@ -995,7 +1018,7 @@ int SCULPT_nearest_vertex_get( }; BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode); if (totnode == 0) { - return -1; + return BKE_pbvh_make_vref(PBVH_REF_NONE); } SculptThreadedTaskData task_data = { @@ -1007,7 +1030,7 @@ int SCULPT_nearest_vertex_get( copy_v3_v3(task_data.nearest_vertex_search_co, co); NearestVertexTLSData nvtd; - nvtd.nearest_vertex_index = -1; + nvtd.nearest_vertex.i = PBVH_REF_NONE; nvtd.nearest_vertex_distance_squared = FLT_MAX; TaskParallelSettings settings; @@ -1019,7 +1042,7 @@ int SCULPT_nearest_vertex_get( MEM_SAFE_FREE(nodes); - return nvtd.nearest_vertex_index; + return nvtd.nearest_vertex; } bool SCULPT_is_symmetry_iteration_valid(char i, char symm) @@ -1074,23 +1097,27 @@ void SCULPT_floodfill_init(SculptSession *ss, SculptFloodFill *flood) int vertex_count = SCULPT_vertex_count_get(ss); SCULPT_vertex_random_access_ensure(ss); - flood->queue = BLI_gsqueue_new(sizeof(int)); + flood->queue = BLI_gsqueue_new(sizeof(intptr_t)); flood->visited_vertices = BLI_BITMAP_NEW(vertex_count, "visited vertices"); } -void SCULPT_floodfill_add_initial(SculptFloodFill *flood, int index) +void SCULPT_floodfill_add_initial(SculptFloodFill *flood, PBVHVertRef vertex) { - BLI_gsqueue_push(flood->queue, &index); + BLI_gsqueue_push(flood->queue, &vertex); } -void SCULPT_floodfill_add_and_skip_initial(SculptFloodFill *flood, int index) +void SCULPT_floodfill_add_and_skip_initial(SculptFloodFill *flood, PBVHVertRef vertex) { - BLI_gsqueue_push(flood->queue, &index); - BLI_BITMAP_ENABLE(flood->visited_vertices, index); + BLI_gsqueue_push(flood->queue, &vertex); + BLI_BITMAP_ENABLE(flood->visited_vertices, vertex.i); } -void SCULPT_floodfill_add_initial_with_symmetry( - Sculpt *sd, Object *ob, SculptSession *ss, SculptFloodFill *flood, int index, float radius) +void SCULPT_floodfill_add_initial_with_symmetry(Sculpt *sd, + Object *ob, + SculptSession *ss, + SculptFloodFill *flood, + PBVHVertRef vertex, + float radius) { /* Add active vertex and symmetric vertices to the queue. */ const char symm = SCULPT_mesh_symmetry_xyz_get(ob); @@ -1098,18 +1125,19 @@ void SCULPT_floodfill_add_initial_with_symmetry( if (!SCULPT_is_symmetry_iteration_valid(i, symm)) { continue; } - int v = -1; + PBVHVertRef v = {PBVH_REF_NONE}; + if (i == 0) { - v = index; + v = vertex; } else if (radius > 0.0f) { float radius_squared = (radius == FLT_MAX) ? FLT_MAX : radius * radius; float location[3]; - flip_v3_v3(location, SCULPT_vertex_co_get(ss, index), i); + flip_v3_v3(location, SCULPT_vertex_co_get(ss, vertex), i); v = SCULPT_nearest_vertex_get(sd, ob, location, radius_squared, false); } - if (v != -1) { + if (v.i != PBVH_REF_NONE) { SCULPT_floodfill_add_initial(flood, v); } } @@ -1124,7 +1152,9 @@ void SCULPT_floodfill_add_active( if (!SCULPT_is_symmetry_iteration_valid(i, symm)) { continue; } - int v = -1; + + PBVHVertRef v = {PBVH_REF_NONE}; + if (i == 0) { v = SCULPT_active_vertex_get(ss); } @@ -1134,26 +1164,31 @@ void SCULPT_floodfill_add_active( v = SCULPT_nearest_vertex_get(sd, ob, location, radius, false); } - if (v != -1) { + if (v.i != PBVH_REF_NONE) { SCULPT_floodfill_add_initial(flood, v); } } } -void SCULPT_floodfill_execute( - SculptSession *ss, - SculptFloodFill *flood, - bool (*func)(SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata), - void *userdata) +void SCULPT_floodfill_execute(SculptSession *ss, + SculptFloodFill *flood, + bool (*func)(SculptSession *ss, + PBVHVertRef from_v, + PBVHVertRef to_v, + bool is_duplicate, + void *userdata), + void *userdata) { while (!BLI_gsqueue_is_empty(flood->queue)) { - int from_v; + PBVHVertRef from_v; + BLI_gsqueue_pop(flood->queue, &from_v); SculptVertexNeighborIter ni; SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) { - const int to_v = ni.index; + const PBVHVertRef to_v = ni.vertex; + int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); - if (BLI_BITMAP_TEST(flood->visited_vertices, to_v)) { + if (BLI_BITMAP_TEST(flood->visited_vertices, to_v_i)) { continue; } @@ -1161,7 +1196,7 @@ void SCULPT_floodfill_execute( continue; } - BLI_BITMAP_ENABLE(flood->visited_vertices, to_v); + BLI_BITMAP_ENABLE(flood->visited_vertices, BKE_pbvh_vertex_to_index(ss->pbvh, to_v)); if (func(ss, from_v, to_v, ni.is_duplicate, userdata)) { BLI_gsqueue_push(flood->queue, &to_v); @@ -1408,14 +1443,14 @@ static void paint_mesh_restore_co_task_cb(void *__restrict userdata, copy_v3_v3(vd.fno, orig_data.no); } if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } else if (orig_data.unode->type == SCULPT_UNDO_MASK) { *vd.mask = orig_data.mask; } else if (orig_data.unode->type == SCULPT_UNDO_COLOR) { - SCULPT_vertex_color_set(ss, vd.index, orig_data.col); + SCULPT_vertex_color_set(ss, vd.vertex, orig_data.col); } } BKE_pbvh_vertex_iter_end; @@ -2359,12 +2394,12 @@ static float brush_strength(const Sculpt *sd, float SCULPT_brush_strength_factor(SculptSession *ss, const Brush *br, const float brush_point[3], - const float len, + float len, const float vno[3], const float fno[3], - const float mask, - const int vertex_index, - const int thread_id) + float mask, + const PBVHVertRef vertex, + int thread_id) { StrokeCache *cache = ss->cache; const Scene *scene = cache->vc->scene; @@ -2448,7 +2483,7 @@ float SCULPT_brush_strength_factor(SculptSession *ss, avg *= 1.0f - mask; /* Auto-masking. */ - avg *= SCULPT_automasking_factor_get(cache->automasking, ss, vertex_index); + avg *= SCULPT_automasking_factor_get(cache->automasking, ss, vertex); return avg; } @@ -2817,7 +2852,7 @@ typedef struct { float depth; bool original; - int active_vertex_index; + PBVHVertRef active_vertex; float *face_normal; int active_face_grid_index; @@ -3037,13 +3072,13 @@ static void do_gravity_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); mul_v3_v3fl(proxy[vd.i], offset, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -4742,7 +4777,7 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin) srd->ray_normal, &srd->isect_precalc, &srd->depth, - &srd->active_vertex_index, + &srd->active_vertex, &srd->active_face_grid_index, srd->face_normal)) { srd->hit = true; @@ -4876,7 +4911,7 @@ bool SCULPT_cursor_geometry_info_update(bContext *C, } /* Update the active vertex of the SculptSession. */ - ss->active_vertex_index = srd.active_vertex_index; + ss->active_vertex = srd.active_vertex; SCULPT_vertex_random_access_ensure(ss); copy_v3_v3(out->active_vertex_co, SCULPT_active_vertex_co_get(ss)); @@ -5621,7 +5656,7 @@ void SCULPT_OT_brush_stroke(wmOperatorType *ot) ot->cancel = sculpt_brush_stroke_cancel; /* Flags (sculpt does own undo? (ton)). */ - ot->flag = OPTYPE_BLOCKING; + ot->flag = OPTYPE_BLOCKING | OPTYPE_REGISTER | OPTYPE_UNDO; /* Properties. */ @@ -5661,10 +5696,10 @@ enum { SCULPT_TOPOLOGY_ID_DEFAULT, }; -static int SCULPT_vertex_get_connected_component(SculptSession *ss, int index) +static int SCULPT_vertex_get_connected_component(SculptSession *ss, PBVHVertRef vertex) { if (ss->vertex_info.connected_component) { - return ss->vertex_info.connected_component[index]; + return ss->vertex_info.connected_component[vertex.i]; } return SCULPT_TOPOLOGY_ID_DEFAULT; } @@ -5681,8 +5716,11 @@ static void SCULPT_fake_neighbor_init(SculptSession *ss, const float max_dist) ss->fake_neighbors.current_max_distance = max_dist; } -static void SCULPT_fake_neighbor_add(SculptSession *ss, int v_index_a, int v_index_b) +static void SCULPT_fake_neighbor_add(SculptSession *ss, PBVHVertRef v_a, PBVHVertRef v_b) { + int v_index_a = BKE_pbvh_vertex_to_index(ss->pbvh, v_a); + int v_index_b = BKE_pbvh_vertex_to_index(ss->pbvh, v_b); + if (ss->fake_neighbors.fake_neighbor_index[v_index_a] == FAKE_NEIGHBOR_NONE) { ss->fake_neighbors.fake_neighbor_index[v_index_a] = v_index_b; ss->fake_neighbors.fake_neighbor_index[v_index_b] = v_index_a; @@ -5695,7 +5733,7 @@ static void sculpt_pose_fake_neighbors_free(SculptSession *ss) } typedef struct NearestVertexFakeNeighborTLSData { - int nearest_vertex_index; + PBVHVertRef nearest_vertex; float nearest_vertex_distance_squared; int current_topology_id; } NearestVertexFakeNeighborTLSData; @@ -5710,13 +5748,13 @@ static void do_fake_neighbor_search_task_cb(void *__restrict userdata, PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - int vd_topology_id = SCULPT_vertex_get_connected_component(ss, vd.index); + int vd_topology_id = SCULPT_vertex_get_connected_component(ss, vd.vertex); if (vd_topology_id != nvtd->current_topology_id && ss->fake_neighbors.fake_neighbor_index[vd.index] == FAKE_NEIGHBOR_NONE) { float distance_squared = len_squared_v3v3(vd.co, data->nearest_vertex_search_co); if (distance_squared < nvtd->nearest_vertex_distance_squared && distance_squared < data->max_distance_squared) { - nvtd->nearest_vertex_index = vd.index; + nvtd->nearest_vertex = vd.vertex; nvtd->nearest_vertex_distance_squared = distance_squared; } } @@ -5730,17 +5768,20 @@ static void fake_neighbor_search_reduce(const void *__restrict UNUSED(userdata), { NearestVertexFakeNeighborTLSData *join = chunk_join; NearestVertexFakeNeighborTLSData *nvtd = chunk; - if (join->nearest_vertex_index == -1) { - join->nearest_vertex_index = nvtd->nearest_vertex_index; + if (join->nearest_vertex.i == PBVH_REF_NONE) { + join->nearest_vertex = nvtd->nearest_vertex; join->nearest_vertex_distance_squared = nvtd->nearest_vertex_distance_squared; } else if (nvtd->nearest_vertex_distance_squared < join->nearest_vertex_distance_squared) { - join->nearest_vertex_index = nvtd->nearest_vertex_index; + join->nearest_vertex = nvtd->nearest_vertex; join->nearest_vertex_distance_squared = nvtd->nearest_vertex_distance_squared; } } -static int SCULPT_fake_neighbor_search(Sculpt *sd, Object *ob, const int index, float max_distance) +static PBVHVertRef SCULPT_fake_neighbor_search(Sculpt *sd, + Object *ob, + const PBVHVertRef vertex, + float max_distance) { SculptSession *ss = ob->sculpt; PBVHNode **nodes = NULL; @@ -5750,12 +5791,12 @@ static int SCULPT_fake_neighbor_search(Sculpt *sd, Object *ob, const int index, .sd = sd, .radius_squared = max_distance * max_distance, .original = false, - .center = SCULPT_vertex_co_get(ss, index), + .center = SCULPT_vertex_co_get(ss, vertex), }; BKE_pbvh_search_gather(ss->pbvh, SCULPT_search_sphere_cb, &data, &nodes, &totnode); if (totnode == 0) { - return -1; + return BKE_pbvh_make_vref(PBVH_REF_NONE); } SculptThreadedTaskData task_data = { @@ -5765,12 +5806,12 @@ static int SCULPT_fake_neighbor_search(Sculpt *sd, Object *ob, const int index, .max_distance_squared = max_distance * max_distance, }; - copy_v3_v3(task_data.nearest_vertex_search_co, SCULPT_vertex_co_get(ss, index)); + copy_v3_v3(task_data.nearest_vertex_search_co, SCULPT_vertex_co_get(ss, vertex)); NearestVertexFakeNeighborTLSData nvtd; - nvtd.nearest_vertex_index = -1; + nvtd.nearest_vertex.i = -1; nvtd.nearest_vertex_distance_squared = FLT_MAX; - nvtd.current_topology_id = SCULPT_vertex_get_connected_component(ss, index); + nvtd.current_topology_id = SCULPT_vertex_get_connected_component(ss, vertex); TaskParallelSettings settings; BKE_pbvh_parallel_range_settings(&settings, true, totnode); @@ -5781,19 +5822,26 @@ static int SCULPT_fake_neighbor_search(Sculpt *sd, Object *ob, const int index, MEM_SAFE_FREE(nodes); - return nvtd.nearest_vertex_index; + return nvtd.nearest_vertex; } typedef struct SculptTopologyIDFloodFillData { int next_id; } SculptTopologyIDFloodFillData; -static bool SCULPT_connected_components_floodfill_cb( - SculptSession *ss, int from_v, int to_v, bool UNUSED(is_duplicate), void *userdata) +static bool SCULPT_connected_components_floodfill_cb(SculptSession *ss, + PBVHVertRef from_v, + PBVHVertRef to_v, + bool UNUSED(is_duplicate), + void *userdata) { SculptTopologyIDFloodFillData *data = userdata; - ss->vertex_info.connected_component[from_v] = data->next_id; - ss->vertex_info.connected_component[to_v] = data->next_id; + + int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); + int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); + + ss->vertex_info.connected_component[from_v_i] = data->next_id; + ss->vertex_info.connected_component[to_v_i] = data->next_id; return true; } @@ -5817,10 +5865,12 @@ void SCULPT_connected_components_ensure(Object *ob) int next_id = 0; for (int i = 0; i < totvert; i++) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + if (ss->vertex_info.connected_component[i] == SCULPT_TOPOLOGY_ID_NONE) { SculptFloodFill flood; SCULPT_floodfill_init(ss, &flood); - SCULPT_floodfill_add_initial(&flood, i); + SCULPT_floodfill_add_initial(&flood, vertex); SculptTopologyIDFloodFillData data; data.next_id = next_id; SCULPT_floodfill_execute(ss, &flood, SCULPT_connected_components_floodfill_cb, &data); @@ -5878,12 +5928,12 @@ void SCULPT_fake_neighbors_ensure(Sculpt *sd, Object *ob, const float max_dist) SCULPT_fake_neighbor_init(ss, max_dist); for (int i = 0; i < totvert; i++) { - const int from_v = i; + const PBVHVertRef from_v = BKE_pbvh_index_to_vertex(ss->pbvh, i); /* This vertex does not have a fake neighbor yet, search one for it. */ - if (ss->fake_neighbors.fake_neighbor_index[from_v] == FAKE_NEIGHBOR_NONE) { - const int to_v = SCULPT_fake_neighbor_search(sd, ob, from_v, max_dist); - if (to_v != -1) { + if (ss->fake_neighbors.fake_neighbor_index[i] == FAKE_NEIGHBOR_NONE) { + const PBVHVertRef to_v = SCULPT_fake_neighbor_search(sd, ob, from_v, max_dist); + if (to_v.i != PBVH_REF_NONE) { /* Add the fake neighbor if available. */ SCULPT_fake_neighbor_add(ss, from_v, to_v); } diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.cc b/source/blender/editors/sculpt_paint/sculpt_automasking.cc index bb101717c9b..a9fe8cc4b2f 100644 --- a/source/blender/editors/sculpt_paint/sculpt_automasking.cc +++ b/source/blender/editors/sculpt_paint/sculpt_automasking.cc @@ -114,16 +114,21 @@ static bool SCULPT_automasking_needs_factors_cache(const Sculpt *sd, const Brush return false; } -float SCULPT_automasking_factor_get(AutomaskingCache *automasking, SculptSession *ss, int vert) +float SCULPT_automasking_factor_get(AutomaskingCache *automasking, + SculptSession *ss, + PBVHVertRef vert) { if (!automasking) { return 1.0f; } + + int index = BKE_pbvh_vertex_to_index(ss->pbvh, vert); + /* If the cache is initialized with valid info, use the cache. This is used when the * automasking information can't be computed in real time per vertex and needs to be * initialized for the whole mesh when the stroke starts. */ if (automasking->factor) { - return automasking->factor[vert]; + return automasking->factor[index]; } if (automasking->settings.flags & BRUSH_AUTOMASKING_FACE_SETS) { @@ -178,13 +183,18 @@ struct AutomaskFloodFillData { char symm; }; -static bool automask_floodfill_cb( - SculptSession *ss, int from_v, int to_v, bool UNUSED(is_duplicate), void *userdata) +static bool automask_floodfill_cb(SculptSession *ss, + PBVHVertRef from_v, + PBVHVertRef to_v, + bool UNUSED(is_duplicate), + void *userdata) { AutomaskFloodFillData *data = (AutomaskFloodFillData *)userdata; + int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); + int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); - data->automask_factor[to_v] = 1.0f; - data->automask_factor[from_v] = 1.0f; + data->automask_factor[to_v_i] = 1.0f; + data->automask_factor[from_v_i] = 1.0f; return (!data->use_radius || SCULPT_is_vertex_inside_brush_radius_symm( SCULPT_vertex_co_get(ss, to_v), data->location, data->radius, data->symm)); @@ -243,7 +253,9 @@ static float *sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob, float *a int tot_vert = SCULPT_vertex_count_get(ss); int active_face_set = SCULPT_active_face_set_get(ss); for (int i : IndexRange(tot_vert)) { - if (!SCULPT_vertex_has_face_set(ss, i, active_face_set)) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + if (!SCULPT_vertex_has_face_set(ss, vertex, active_face_set)) { automask_factor[i] *= 0.0f; } } @@ -269,15 +281,17 @@ float *SCULPT_boundary_automasking_init(Object *ob, int *edge_distance = (int *)MEM_callocN(sizeof(int) * totvert, "automask_factor"); for (int i : IndexRange(totvert)) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + edge_distance[i] = EDGE_DISTANCE_INF; switch (mode) { case AUTOMASK_INIT_BOUNDARY_EDGES: - if (SCULPT_vertex_is_boundary(ss, i)) { + if (SCULPT_vertex_is_boundary(ss, vertex)) { edge_distance[i] = 0; } break; case AUTOMASK_INIT_BOUNDARY_FACE_SETS: - if (!SCULPT_vertex_has_unique_face_set(ss, i)) { + if (!SCULPT_vertex_has_unique_face_set(ss, vertex)) { edge_distance[i] = 0; } break; @@ -286,11 +300,13 @@ float *SCULPT_boundary_automasking_init(Object *ob, for (int propagation_it : IndexRange(propagation_steps)) { for (int i : IndexRange(totvert)) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + if (edge_distance[i] != EDGE_DISTANCE_INF) { continue; } SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { if (edge_distance[ni.index] == propagation_it) { edge_distance[i] = propagation_it + 1; } diff --git a/source/blender/editors/sculpt_paint/sculpt_boundary.c b/source/blender/editors/sculpt_paint/sculpt_boundary.c index 390fcb9648a..8d08c338b93 100644 --- a/source/blender/editors/sculpt_paint/sculpt_boundary.c +++ b/source/blender/editors/sculpt_paint/sculpt_boundary.c @@ -46,32 +46,38 @@ #define BOUNDARY_STEPS_NONE -1 typedef struct BoundaryInitialVertexFloodFillData { - int initial_vertex; + PBVHVertRef initial_vertex; + int initial_vertex_i; int boundary_initial_vertex_steps; - int boundary_initial_vertex; + PBVHVertRef boundary_initial_vertex; + int boundary_initial_vertex_i; int *floodfill_steps; float radius_sq; } BoundaryInitialVertexFloodFillData; static bool boundary_initial_vertex_floodfill_cb( - SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata) + SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata) { BoundaryInitialVertexFloodFillData *data = userdata; + int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); + int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); + if (!SCULPT_vertex_visible_get(ss, to_v)) { return false; } if (!is_duplicate) { - data->floodfill_steps[to_v] = data->floodfill_steps[from_v] + 1; + data->floodfill_steps[to_v_i] = data->floodfill_steps[from_v_i] + 1; } else { - data->floodfill_steps[to_v] = data->floodfill_steps[from_v]; + data->floodfill_steps[to_v_i] = data->floodfill_steps[from_v_i]; } if (SCULPT_vertex_is_boundary(ss, to_v)) { - if (data->floodfill_steps[to_v] < data->boundary_initial_vertex_steps) { - data->boundary_initial_vertex_steps = data->floodfill_steps[to_v]; + if (data->floodfill_steps[to_v_i] < data->boundary_initial_vertex_steps) { + data->boundary_initial_vertex_steps = data->floodfill_steps[to_v_i]; + data->boundary_initial_vertex_i = to_v_i; data->boundary_initial_vertex = to_v; } } @@ -83,9 +89,9 @@ static bool boundary_initial_vertex_floodfill_cb( /* From a vertex index anywhere in the mesh, returns the closest vertex in a mesh boundary inside * the given radius, if it exists. */ -static int sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss, - const int initial_vertex, - const float radius) +static PBVHVertRef sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss, + const PBVHVertRef initial_vertex, + const float radius) { if (SCULPT_vertex_is_boundary(ss, initial_vertex)) { @@ -98,7 +104,7 @@ static int sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss, BoundaryInitialVertexFloodFillData fdata = { .initial_vertex = initial_vertex, - .boundary_initial_vertex = BOUNDARY_VERTEX_NONE, + .boundary_initial_vertex = {BOUNDARY_VERTEX_NONE}, .boundary_initial_vertex_steps = INT_MAX, .radius_sq = radius * radius, }; @@ -119,12 +125,14 @@ static int sculpt_boundary_get_closest_boundary_vertex(SculptSession *ss, static int BOUNDARY_INDICES_BLOCK_SIZE = 300; static void sculpt_boundary_index_add(SculptBoundary *boundary, + const PBVHVertRef new_vertex, const int new_index, const float distance, GSet *included_vertices) { - boundary->vertices[boundary->num_vertices] = new_index; + boundary->vertices[boundary->num_vertices] = new_vertex; + if (boundary->distance) { boundary->distance[new_index] = distance; } @@ -135,11 +143,13 @@ static void sculpt_boundary_index_add(SculptBoundary *boundary, if (boundary->num_vertices >= boundary->vertices_capacity) { boundary->vertices_capacity += BOUNDARY_INDICES_BLOCK_SIZE; boundary->vertices = MEM_reallocN_id( - boundary->vertices, boundary->vertices_capacity * sizeof(int), "boundary indices"); + boundary->vertices, boundary->vertices_capacity * sizeof(PBVHVertRef), "boundary indices"); } }; -static void sculpt_boundary_preview_edge_add(SculptBoundary *boundary, const int v1, const int v2) +static void sculpt_boundary_preview_edge_add(SculptBoundary *boundary, + const PBVHVertRef v1, + const PBVHVertRef v2) { boundary->edges[boundary->num_edges].v1 = v1; @@ -159,7 +169,7 @@ static void sculpt_boundary_preview_edge_add(SculptBoundary *boundary, const int * as well as to check if the initial vertex is valid. */ static bool sculpt_boundary_is_vertex_in_editable_boundary(SculptSession *ss, - const int initial_vertex) + const PBVHVertRef initial_vertex) { if (!SCULPT_vertex_visible_get(ss, initial_vertex)) { @@ -170,9 +180,9 @@ static bool sculpt_boundary_is_vertex_in_editable_boundary(SculptSession *ss, int boundary_vertex_count = 0; SculptVertexNeighborIter ni; SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, initial_vertex, ni) { - if (SCULPT_vertex_visible_get(ss, ni.index)) { + if (SCULPT_vertex_visible_get(ss, ni.vertex)) { neighbor_count++; - if (SCULPT_vertex_is_boundary(ss, ni.index)) { + if (SCULPT_vertex_is_boundary(ss, ni.vertex)) { boundary_vertex_count++; } } @@ -202,13 +212,16 @@ typedef struct BoundaryFloodFillData { GSet *included_vertices; EdgeSet *preview_edges; - int last_visited_vertex; + PBVHVertRef last_visited_vertex; } BoundaryFloodFillData; static bool boundary_floodfill_cb( - SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata) + SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata) { + int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); + int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); + BoundaryFloodFillData *data = userdata; SculptBoundary *boundary = data->boundary; if (!SCULPT_vertex_is_boundary(ss, to_v)) { @@ -217,9 +230,10 @@ static bool boundary_floodfill_cb( const float edge_len = len_v3v3(SCULPT_vertex_co_get(ss, from_v), SCULPT_vertex_co_get(ss, to_v)); const float distance_boundary_to_dst = boundary->distance ? - boundary->distance[from_v] + edge_len : + boundary->distance[from_v_i] + edge_len : 0.0f; - sculpt_boundary_index_add(boundary, to_v, distance_boundary_to_dst, data->included_vertices); + sculpt_boundary_index_add( + boundary, to_v, to_v_i, distance_boundary_to_dst, data->included_vertices); if (!is_duplicate) { sculpt_boundary_preview_edge_add(boundary, from_v, to_v); } @@ -229,12 +243,13 @@ static bool boundary_floodfill_cb( static void sculpt_boundary_indices_init(SculptSession *ss, SculptBoundary *boundary, const bool init_boundary_distances, - const int initial_boundary_index) + const PBVHVertRef initial_boundary_vertex) { const int totvert = SCULPT_vertex_count_get(ss); boundary->vertices = MEM_malloc_arrayN( - BOUNDARY_INDICES_BLOCK_SIZE, sizeof(int), "boundary indices"); + BOUNDARY_INDICES_BLOCK_SIZE, sizeof(PBVHVertRef), "boundary indices"); + if (init_boundary_distances) { boundary->distance = MEM_calloc_arrayN(totvert, sizeof(float), "boundary distances"); } @@ -245,16 +260,21 @@ static void sculpt_boundary_indices_init(SculptSession *ss, SculptFloodFill flood; SCULPT_floodfill_init(ss, &flood); - boundary->initial_vertex = initial_boundary_index; + int initial_boundary_index = BKE_pbvh_vertex_to_index(ss->pbvh, initial_boundary_vertex); + + boundary->initial_vertex = initial_boundary_vertex; + boundary->initial_vertex_i = initial_boundary_index; + copy_v3_v3(boundary->initial_vertex_position, SCULPT_vertex_co_get(ss, boundary->initial_vertex)); - sculpt_boundary_index_add(boundary, initial_boundary_index, 0.0f, included_vertices); - SCULPT_floodfill_add_initial(&flood, initial_boundary_index); + sculpt_boundary_index_add( + boundary, initial_boundary_vertex, initial_boundary_index, 0.0f, included_vertices); + SCULPT_floodfill_add_initial(&flood, boundary->initial_vertex); BoundaryFloodFillData fdata = { .boundary = boundary, .included_vertices = included_vertices, - .last_visited_vertex = BOUNDARY_VERTEX_NONE, + .last_visited_vertex = {BOUNDARY_VERTEX_NONE}, }; @@ -262,13 +282,13 @@ static void sculpt_boundary_indices_init(SculptSession *ss, SCULPT_floodfill_free(&flood); /* Check if the boundary loops into itself and add the extra preview edge to close the loop. */ - if (fdata.last_visited_vertex != BOUNDARY_VERTEX_NONE && + if (fdata.last_visited_vertex.i != BOUNDARY_VERTEX_NONE && sculpt_boundary_is_vertex_in_editable_boundary(ss, fdata.last_visited_vertex)) { SculptVertexNeighborIter ni; SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, fdata.last_visited_vertex, ni) { if (BLI_gset_haskey(included_vertices, POINTER_FROM_INT(ni.index)) && - sculpt_boundary_is_vertex_in_editable_boundary(ss, ni.index)) { - sculpt_boundary_preview_edge_add(boundary, fdata.last_visited_vertex, ni.index); + sculpt_boundary_is_vertex_in_editable_boundary(ss, ni.vertex)) { + sculpt_boundary_preview_edge_add(boundary, fdata.last_visited_vertex, ni.vertex); boundary->forms_loop = true; } } @@ -286,7 +306,7 @@ static void sculpt_boundary_indices_init(SculptSession *ss, */ static void sculpt_boundary_edit_data_init(SculptSession *ss, SculptBoundary *boundary, - const int initial_vertex, + const PBVHVertRef initial_vertex, const float radius) { const int totvert = SCULPT_vertex_count_get(ss); @@ -297,19 +317,22 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, totvert, sizeof(SculptBoundaryEditInfo), "Boundary edit info"); for (int i = 0; i < totvert; i++) { - boundary->edit_info[i].original_vertex = BOUNDARY_VERTEX_NONE; + boundary->edit_info[i].original_vertex_i = BOUNDARY_VERTEX_NONE; boundary->edit_info[i].num_propagation_steps = BOUNDARY_STEPS_NONE; } - GSQueue *current_iteration = BLI_gsqueue_new(sizeof(int)); - GSQueue *next_iteration = BLI_gsqueue_new(sizeof(int)); + GSQueue *current_iteration = BLI_gsqueue_new(sizeof(PBVHVertRef)); + GSQueue *next_iteration = BLI_gsqueue_new(sizeof(PBVHVertRef)); /* Initialized the first iteration with the vertices already in the boundary. This is propagation * step 0. */ BLI_bitmap *visited_vertices = BLI_BITMAP_NEW(SCULPT_vertex_count_get(ss), "visited_vertices"); for (int i = 0; i < boundary->num_vertices; i++) { - boundary->edit_info[boundary->vertices[i]].original_vertex = boundary->vertices[i]; - boundary->edit_info[boundary->vertices[i]].num_propagation_steps = 0; + int index = BKE_pbvh_vertex_to_index(ss->pbvh, boundary->vertices[i]); + + boundary->edit_info[index].original_vertex_i = BKE_pbvh_vertex_to_index(ss->pbvh, + boundary->vertices[i]); + boundary->edit_info[index].num_propagation_steps = 0; /* This ensures that all duplicate vertices in the boundary have the same original_vertex * index, so the deformation for them will be the same. */ @@ -317,7 +340,8 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, SculptVertexNeighborIter ni_duplis; SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, boundary->vertices[i], ni_duplis) { if (ni_duplis.is_duplicate) { - boundary->edit_info[ni_duplis.index].original_vertex = boundary->vertices[i]; + boundary->edit_info[ni_duplis.index].original_vertex_i = BKE_pbvh_vertex_to_index( + ss->pbvh, boundary->vertices[i]); } } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis); @@ -338,31 +362,33 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, } while (!BLI_gsqueue_is_empty(current_iteration)) { - int from_v; + PBVHVertRef from_v; BLI_gsqueue_pop(current_iteration, &from_v); + int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); + SculptVertexNeighborIter ni; SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) { - const bool is_visible = SCULPT_vertex_visible_get(ss, ni.index); + const bool is_visible = SCULPT_vertex_visible_get(ss, ni.vertex); if (!is_visible || boundary->edit_info[ni.index].num_propagation_steps != BOUNDARY_STEPS_NONE) { continue; } - boundary->edit_info[ni.index].original_vertex = - boundary->edit_info[from_v].original_vertex; + boundary->edit_info[ni.index].original_vertex_i = + boundary->edit_info[from_v_i].original_vertex_i; BLI_BITMAP_ENABLE(visited_vertices, ni.index); if (ni.is_duplicate) { /* Grids duplicates handling. */ boundary->edit_info[ni.index].num_propagation_steps = - boundary->edit_info[from_v].num_propagation_steps; + boundary->edit_info[from_v_i].num_propagation_steps; } else { boundary->edit_info[ni.index].num_propagation_steps = - boundary->edit_info[from_v].num_propagation_steps + 1; + boundary->edit_info[from_v_i].num_propagation_steps + 1; - BLI_gsqueue_push(next_iteration, &ni.index); + BLI_gsqueue_push(next_iteration, &ni.vertex); /* When copying the data to the neighbor for the next iteration, it has to be copied to * all its duplicates too. This is because it is not possible to know if the updated @@ -370,12 +396,12 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, * copy the data in the from_v neighbor iterator. */ if (has_duplicates) { SculptVertexNeighborIter ni_duplis; - SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.index, ni_duplis) { + SCULPT_VERTEX_DUPLICATES_AND_NEIGHBORS_ITER_BEGIN (ss, ni.vertex, ni_duplis) { if (ni_duplis.is_duplicate) { - boundary->edit_info[ni_duplis.index].original_vertex = - boundary->edit_info[from_v].original_vertex; + boundary->edit_info[ni_duplis.index].original_vertex_i = + boundary->edit_info[from_v_i].original_vertex_i; boundary->edit_info[ni_duplis.index].num_propagation_steps = - boundary->edit_info[from_v].num_propagation_steps + 1; + boundary->edit_info[from_v_i].num_propagation_steps + 1; } } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni_duplis); @@ -383,11 +409,12 @@ static void sculpt_boundary_edit_data_init(SculptSession *ss, /* Check the distance using the vertex that was propagated from the initial vertex that * was used to initialize the boundary. */ - if (boundary->edit_info[from_v].original_vertex == initial_vertex) { - boundary->pivot_vertex = ni.index; - copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.index)); + if (boundary->edit_info[from_v_i].original_vertex_i == + BKE_pbvh_vertex_to_index(ss->pbvh, initial_vertex)) { + boundary->pivot_vertex = ni.vertex; + copy_v3_v3(boundary->initial_pivot_position, SCULPT_vertex_co_get(ss, ni.vertex)); accum_distance += len_v3v3(SCULPT_vertex_co_get(ss, from_v), - SCULPT_vertex_co_get(ss, ni.index)); + SCULPT_vertex_co_get(ss, ni.vertex)); } } } @@ -427,7 +454,8 @@ static void sculpt_boundary_falloff_factor_init(SculptSession *ss, brush, boundary->edit_info[i].num_propagation_steps, boundary->max_propagation_steps); } - if (boundary->edit_info[i].original_vertex == boundary->initial_vertex) { + if (boundary->edit_info[i].original_vertex_i == + BKE_pbvh_vertex_to_index(ss->pbvh, boundary->initial_vertex)) { /* All vertices that are propagated from the original vertex won't be affected by the * boundary falloff, so there is no need to calculate anything else. */ continue; @@ -439,7 +467,7 @@ static void sculpt_boundary_falloff_factor_init(SculptSession *ss, continue; } - const float boundary_distance = boundary->distance[boundary->edit_info[i].original_vertex]; + const float boundary_distance = boundary->distance[boundary->edit_info[i].original_vertex_i]; float falloff_distance = 0.0f; float direction = 1.0f; @@ -473,22 +501,22 @@ static void sculpt_boundary_falloff_factor_init(SculptSession *ss, SculptBoundary *SCULPT_boundary_data_init(Object *object, Brush *brush, - const int initial_vertex, + const PBVHVertRef initial_vertex, const float radius) { SculptSession *ss = object->sculpt; - if (initial_vertex == BOUNDARY_VERTEX_NONE) { + if (initial_vertex.i == PBVH_REF_NONE) { return NULL; } SCULPT_vertex_random_access_ensure(ss); SCULPT_boundary_info_ensure(object); - const int boundary_initial_vertex = sculpt_boundary_get_closest_boundary_vertex( + const PBVHVertRef boundary_initial_vertex = sculpt_boundary_get_closest_boundary_vertex( ss, initial_vertex, radius); - if (boundary_initial_vertex == BOUNDARY_VERTEX_NONE) { + if (boundary_initial_vertex.i == BOUNDARY_VERTEX_NONE) { return NULL; } @@ -539,17 +567,22 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) { continue; } + + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + float dir[3]; float normal[3]; - SCULPT_vertex_normal_get(ss, i, normal); - sub_v3_v3v3(dir, - SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex), - SCULPT_vertex_co_get(ss, i)); + SCULPT_vertex_normal_get(ss, vertex, normal); + sub_v3_v3v3( + dir, + SCULPT_vertex_co_get( + ss, BKE_pbvh_index_to_vertex(ss->pbvh, boundary->edit_info[i].original_vertex_i)), + SCULPT_vertex_co_get(ss, vertex)); cross_v3_v3v3( - boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex], dir, normal); - normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]); - copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex], - SCULPT_vertex_co_get(ss, i)); + boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex_i], dir, normal); + normalize_v3(boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex_i]); + copy_v3_v3(boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex_i], + SCULPT_vertex_co_get(ss, vertex)); } for (int i = 0; i < totvert; i++) { @@ -557,9 +590,9 @@ static void sculpt_boundary_bend_data_init(SculptSession *ss, SculptBoundary *bo continue; } copy_v3_v3(boundary->bend.pivot_positions[i], - boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex]); + boundary->bend.pivot_positions[boundary->edit_info[i].original_vertex_i]); copy_v3_v3(boundary->bend.pivot_rotation_axis[i], - boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex]); + boundary->bend.pivot_rotation_axis[boundary->edit_info[i].original_vertex_i]); } } @@ -572,10 +605,12 @@ static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *b if (boundary->edit_info[i].num_propagation_steps != boundary->max_propagation_steps) { continue; } - sub_v3_v3v3(boundary->slide.directions[boundary->edit_info[i].original_vertex], - SCULPT_vertex_co_get(ss, boundary->edit_info[i].original_vertex), - SCULPT_vertex_co_get(ss, i)); - normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex]); + sub_v3_v3v3( + boundary->slide.directions[boundary->edit_info[i].original_vertex_i], + SCULPT_vertex_co_get( + ss, BKE_pbvh_index_to_vertex(ss->pbvh, boundary->edit_info[i].original_vertex_i)), + SCULPT_vertex_co_get(ss, BKE_pbvh_index_to_vertex(ss->pbvh, i))); + normalize_v3(boundary->slide.directions[boundary->edit_info[i].original_vertex_i]); } for (int i = 0; i < totvert; i++) { @@ -583,7 +618,7 @@ static void sculpt_boundary_slide_data_init(SculptSession *ss, SculptBoundary *b continue; } copy_v3_v3(boundary->slide.directions[i], - boundary->slide.directions[boundary->edit_info[i].original_vertex]); + boundary->slide.directions[boundary->edit_info[i].original_vertex_i]); } } @@ -660,7 +695,7 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata, } const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; - const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index); + const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex); float t_orig_co[3]; float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); sub_v3_v3v3(t_orig_co, orig_data.co, boundary->bend.pivot_positions[vd.index]); @@ -671,7 +706,7 @@ static void do_boundary_brush_bend_task_cb_ex(void *__restrict userdata, add_v3_v3(target_co, boundary->bend.pivot_positions[vd.index]); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -708,7 +743,7 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata, } const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; - const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index); + const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex); float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); madd_v3_v3v3fl(target_co, orig_data.co, @@ -717,7 +752,7 @@ static void do_boundary_brush_slide_task_cb_ex(void *__restrict userdata, strength); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -754,7 +789,7 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata, } const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; - const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index); + const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex); float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); madd_v3_v3v3fl(target_co, orig_data.co, @@ -763,7 +798,7 @@ static void do_boundary_brush_inflate_task_cb_ex(void *__restrict userdata, strength); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -798,7 +833,7 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata, } const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; - const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index); + const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex); float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); madd_v3_v3v3fl(target_co, orig_data.co, @@ -806,7 +841,7 @@ static void do_boundary_brush_grab_task_cb_ex(void *__restrict userdata, boundary->edit_info[vd.index].strength_factor * mask * automask * strength); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -849,7 +884,7 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata, } const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; - const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index); + const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex); float t_orig_co[3]; float *target_co = SCULPT_brush_deform_target_vertex_co_get(ss, brush->deform_target, &vd); sub_v3_v3v3(t_orig_co, orig_data.co, boundary->twist.pivot_position); @@ -860,7 +895,7 @@ static void do_boundary_brush_twist_task_cb_ex(void *__restrict userdata, add_v3_v3(target_co, boundary->twist.pivot_position); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -898,9 +933,9 @@ static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata, int total_neighbors = 0; const int current_propagation_steps = boundary->edit_info[vd.index].num_propagation_steps; SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) { if (current_propagation_steps == boundary->edit_info[ni.index].num_propagation_steps) { - add_v3_v3(coord_accum, SCULPT_vertex_co_get(ss, ni.index)); + add_v3_v3(coord_accum, SCULPT_vertex_co_get(ss, ni.vertex)); total_neighbors++; } } @@ -919,7 +954,7 @@ static void do_boundary_brush_smooth_task_cb_ex(void *__restrict userdata, target_co, vd.co, disp, boundary->edit_info[vd.index].strength_factor * mask * strength); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -933,7 +968,8 @@ void SCULPT_do_boundary_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn const int symm_area = ss->cache->mirror_symmetry_pass; if (SCULPT_stroke_is_first_brush_step_of_symmetry_pass(ss->cache)) { - int initial_vertex; + PBVHVertRef initial_vertex; + if (ss->cache->mirror_symmetry_pass == 0) { initial_vertex = SCULPT_active_vertex_get(ss); } diff --git a/source/blender/editors/sculpt_paint/sculpt_brush_types.c b/source/blender/editors/sculpt_paint/sculpt_brush_types.c index c607dd02a77..245cbe0f54e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_brush_types.c +++ b/source/blender/editors/sculpt_paint/sculpt_brush_types.c @@ -314,13 +314,13 @@ static void do_draw_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); mul_v3_v3fl(proxy[vd.i], offset, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -412,13 +412,13 @@ static void do_fill_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); mul_v3_v3fl(proxy[vd.i], val, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -510,13 +510,13 @@ static void do_scrape_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); mul_v3_v3fl(proxy[vd.i], val, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -628,13 +628,13 @@ static void do_clay_thumb_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); mul_v3_v3fl(proxy[vd.i], val, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -783,13 +783,13 @@ static void do_flatten_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); mul_v3_v3fl(proxy[vd.i], val, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } } @@ -940,13 +940,13 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); mul_v3_v3fl(proxy[vd.i], val, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -1066,13 +1066,13 @@ static void do_clay_strips_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); mul_v3_v3fl(proxy[vd.i], val, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -1219,7 +1219,7 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); } @@ -1267,12 +1267,12 @@ static void do_snake_hook_brush_task_cb_ex(void *__restrict userdata, if (vd.mask) { mul_v3_fl(disp, 1.0f - *vd.mask); } - mul_v3_fl(disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index)); + mul_v3_fl(disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex)); copy_v3_v3(proxy[vd.i], disp); } if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -1352,13 +1352,13 @@ static void do_thumb_brush_task_cb_ex(void *__restrict userdata, orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); mul_v3_v3fl(proxy[vd.i], cono, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -1426,7 +1426,7 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata, orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); sub_v3_v3v3(vec, orig_data.co, ss->cache->location); @@ -1436,7 +1436,7 @@ static void do_rotate_brush_task_cb_ex(void *__restrict userdata, sub_v3_v3(proxy[vd.i], orig_data.co); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -1497,7 +1497,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); const int vi = vd.index; @@ -1533,9 +1533,10 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata, float normal[3]; if (use_persistent_base) { - SCULPT_vertex_persistent_normal_get(ss, vi, normal); + SCULPT_vertex_persistent_normal_get(ss, vd.vertex, normal); mul_v3_fl(normal, brush->height); - madd_v3_v3v3fl(final_co, SCULPT_vertex_persistent_co_get(ss, vi), normal, *disp_factor); + madd_v3_v3v3fl( + final_co, SCULPT_vertex_persistent_co_get(ss, vd.vertex), normal, *disp_factor); } else { copy_v3_v3(normal, orig_data.no); @@ -1551,7 +1552,7 @@ static void do_layer_brush_task_cb_ex(void *__restrict userdata, SCULPT_clip(sd, ss, vd.co, final_co); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -1609,7 +1610,7 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); float val[3]; @@ -1624,7 +1625,7 @@ static void do_inflate_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3v3(proxy[vd.i], val, ss->cache->scale); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -1677,13 +1678,13 @@ static void do_nudge_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); mul_v3_v3fl(proxy[vd.i], cono, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -1756,7 +1757,7 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); float val1[3]; float val2[3]; @@ -1777,7 +1778,7 @@ static void do_crease_brush_task_cb_ex(void *__restrict userdata, add_v3_v3v3(proxy[vd.i], val1, val2); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -1872,7 +1873,7 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); float disp_center[3]; float x_disp[3]; @@ -1896,7 +1897,7 @@ static void do_pinch_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], disp_center, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -1988,7 +1989,7 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata, orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); if (grab_silhouette) { @@ -2005,7 +2006,7 @@ static void do_grab_brush_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], grab_delta, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -2108,12 +2109,12 @@ static void do_elastic_deform_brush_task_cb_ex(void *__restrict userdata, mul_v3_fl(final_disp, 1.0f - *vd.mask); } - mul_v3_fl(final_disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index)); + mul_v3_fl(final_disp, SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex)); copy_v3_v3(proxy[vd.i], final_disp); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -2185,13 +2186,13 @@ static void do_draw_sharp_brush_task_cb_ex(void *__restrict userdata, orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); mul_v3_v3fl(proxy[vd.i], offset, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -2268,7 +2269,7 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata, orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); float current_disp[3]; float current_disp_norm[3]; @@ -2290,10 +2291,10 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(current_disp, current_disp_norm, ss->cache->bstrength); SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) { float vertex_disp[3]; float vertex_disp_norm[3]; - sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co); + sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.vertex), vd.co); normalize_v3_v3(vertex_disp_norm, vertex_disp); if (dot_v3v3(current_disp_norm, vertex_disp_norm) > 0.0f) { madd_v3_v3fl(final_disp, vertex_disp_norm, dot_v3v3(current_disp, vertex_disp)); @@ -2304,7 +2305,7 @@ static void do_topology_slide_task_cb_ex(void *__restrict userdata, mul_v3_v3fl(proxy[vd.i], final_disp, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -2323,31 +2324,31 @@ void SCULPT_relax_vertex(SculptSession *ss, int neighbor_count = 0; zero_v3(smooth_pos); zero_v3(boundary_normal); - const bool is_boundary = SCULPT_vertex_is_boundary(ss, vd->index); + const bool is_boundary = SCULPT_vertex_is_boundary(ss, vd->vertex); SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd->index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd->vertex, ni) { neighbor_count++; if (!filter_boundary_face_sets || - (filter_boundary_face_sets && !SCULPT_vertex_has_unique_face_set(ss, ni.index))) { + (filter_boundary_face_sets && !SCULPT_vertex_has_unique_face_set(ss, ni.vertex))) { /* When the vertex to relax is boundary, use only connected boundary vertices for the average * position. */ if (is_boundary) { - if (!SCULPT_vertex_is_boundary(ss, ni.index)) { + if (!SCULPT_vertex_is_boundary(ss, ni.vertex)) { continue; } - add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index)); + add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.vertex)); avg_count++; /* Calculate a normal for the constraint plane using the edges of the boundary. */ float to_neighbor[3]; - sub_v3_v3v3(to_neighbor, SCULPT_vertex_co_get(ss, ni.index), vd->co); + sub_v3_v3v3(to_neighbor, SCULPT_vertex_co_get(ss, ni.vertex), vd->co); normalize_v3(to_neighbor); add_v3_v3(boundary_normal, to_neighbor); } else { - add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.index)); + add_v3_v3(smooth_pos, SCULPT_vertex_co_get(ss, ni.vertex)); avg_count++; } } @@ -2376,7 +2377,7 @@ void SCULPT_relax_vertex(SculptSession *ss, normalize_v3_v3(vno, boundary_normal); } else { - SCULPT_vertex_normal_get(ss, vd->index, vno); + SCULPT_vertex_normal_get(ss, vd->vertex, vno); } if (is_zero_v3(vno)) { @@ -2425,12 +2426,12 @@ static void do_topology_relax_task_cb_ex(void *__restrict userdata, orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); SCULPT_relax_vertex(ss, &vd, fade * bstrength, false, vd.co); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -2501,17 +2502,17 @@ static void do_displacement_eraser_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); float limit_co[3]; float disp[3]; - SCULPT_vertex_limit_surface_get(ss, vd.index, limit_co); + SCULPT_vertex_limit_surface_get(ss, vd.vertex, limit_co); sub_v3_v3v3(disp, limit_co, vd.co); mul_v3_v3fl(proxy[vd.i], disp, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -2567,7 +2568,7 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); float current_disp[3]; @@ -2594,11 +2595,11 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata, float weights_accum = 1.0f; SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) { float vertex_disp[3]; float vertex_disp_norm[3]; float neighbor_limit_co[3]; - SCULPT_vertex_limit_surface_get(ss, ni.index, neighbor_limit_co); + SCULPT_vertex_limit_surface_get(ss, ni.vertex, neighbor_limit_co); sub_v3_v3v3(vertex_disp, ss->cache->limit_surface_co[ni.index], ss->cache->limit_surface_co[vd.index]); @@ -2623,7 +2624,7 @@ static void do_displacement_smear_brush_task_cb_ex(void *__restrict userdata, interp_v3_v3v3(vd.co, vd.co, new_co, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -2638,7 +2639,7 @@ static void do_displacement_smear_store_prev_disp_task_cb_ex( PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { sub_v3_v3v3(ss->cache->prev_displacement[vd.index], - SCULPT_vertex_co_get(ss, vd.index), + SCULPT_vertex_co_get(ss, vd.vertex), ss->cache->limit_surface_co[vd.index]); } BKE_pbvh_vertex_iter_end; @@ -2657,9 +2658,11 @@ void SCULPT_do_displacement_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes totvert, sizeof(float[3]), "prev displacement"); ss->cache->limit_surface_co = MEM_malloc_arrayN(totvert, sizeof(float[3]), "limit surface co"); for (int i = 0; i < totvert; i++) { - SCULPT_vertex_limit_surface_get(ss, i, ss->cache->limit_surface_co[i]); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + SCULPT_vertex_limit_surface_get(ss, vertex, ss->cache->limit_surface_co[i]); sub_v3_v3v3(ss->cache->prev_displacement[i], - SCULPT_vertex_co_get(ss, i), + SCULPT_vertex_co_get(ss, vertex), ss->cache->limit_surface_co[i]); } } @@ -2722,7 +2725,7 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata, const float fade = bstrength * SCULPT_brush_strength_factor( - ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, *vd.mask, vd.index, thread_id) * + ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, *vd.mask, vd.vertex, thread_id) * ss->cache->pressure; float avg[3], val[3]; @@ -2736,7 +2739,7 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata, SCULPT_clip(sd, ss, vd.co, val); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -2799,7 +2802,7 @@ static void do_mask_brush_draw_task_cb_ex(void *__restrict userdata, } const float fade = SCULPT_brush_strength_factor( - ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.index, thread_id); + ss, brush, vd.co, sqrtf(test.dist), vd.no, vd.fno, 0.0f, vd.vertex, thread_id); if (bstrength > 0.0f) { (*vd.mask) += fade * bstrength * (1.0f - *vd.mask); diff --git a/source/blender/editors/sculpt_paint/sculpt_cloth.c b/source/blender/editors/sculpt_paint/sculpt_cloth.c index e29b2172ea7..b4b2c4e48c8 100644 --- a/source/blender/editors/sculpt_paint/sculpt_cloth.c +++ b/source/blender/editors/sculpt_paint/sculpt_cloth.c @@ -220,13 +220,16 @@ static void cloth_brush_add_length_constraint(SculptSession *ss, length_constraint->type = SCULPT_CLOTH_CONSTRAINT_STRUCTURAL; + PBVHVertRef vertex1 = BKE_pbvh_index_to_vertex(ss->pbvh, v1); + PBVHVertRef vertex2 = BKE_pbvh_index_to_vertex(ss->pbvh, v2); + if (use_persistent) { - length_constraint->length = len_v3v3(SCULPT_vertex_persistent_co_get(ss, v1), - SCULPT_vertex_persistent_co_get(ss, v2)); + length_constraint->length = len_v3v3(SCULPT_vertex_persistent_co_get(ss, vertex1), + SCULPT_vertex_persistent_co_get(ss, vertex2)); } else { - length_constraint->length = len_v3v3(SCULPT_vertex_co_get(ss, v1), - SCULPT_vertex_co_get(ss, v2)); + length_constraint->length = len_v3v3(SCULPT_vertex_co_get(ss, vertex1), + SCULPT_vertex_co_get(ss, vertex2)); } length_constraint->strength = 1.0f; @@ -370,7 +373,7 @@ static void do_cloth_brush_build_constraints_task_cb_ex( int tot_indices = 0; build_indices[tot_indices] = vd.index; tot_indices++; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) { build_indices[tot_indices] = ni.index; tot_indices++; } @@ -540,7 +543,7 @@ static void do_cloth_brush_apply_forces_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); float brush_disp[3]; @@ -784,7 +787,7 @@ static void do_cloth_brush_solve_simulation_task_cb_ex( mul_v3_fl(pos_diff, (1.0f - cloth_sim->damping) * sim_factor); const float mask_v = (1.0f - (vd.mask ? *vd.mask : 0.0f)) * - SCULPT_automasking_factor_get(automasking, ss, vd.index); + SCULPT_automasking_factor_get(automasking, ss, vd.vertex); madd_v3_v3fl(cloth_sim->pos[i], pos_diff, mask_v); madd_v3_v3fl(cloth_sim->pos[i], cloth_sim->acceleration[i], mask_v); @@ -802,7 +805,7 @@ static void do_cloth_brush_solve_simulation_task_cb_ex( copy_v3_v3(vd.co, cloth_sim->pos[vd.index]); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -852,10 +855,13 @@ static void cloth_brush_satisfy_constraints(SculptSession *ss, mul_v3_v3fl(correction_vector_half, correction_vector, 0.5f); - const float mask_v1 = (1.0f - SCULPT_vertex_mask_get(ss, v1)) * - SCULPT_automasking_factor_get(automasking, ss, v1); - const float mask_v2 = (1.0f - SCULPT_vertex_mask_get(ss, v2)) * - SCULPT_automasking_factor_get(automasking, ss, v2); + PBVHVertRef vertex1 = BKE_pbvh_index_to_vertex(ss->pbvh, v1); + PBVHVertRef vertex2 = BKE_pbvh_index_to_vertex(ss->pbvh, v2); + + const float mask_v1 = (1.0f - SCULPT_vertex_mask_get(ss, vertex1)) * + SCULPT_automasking_factor_get(automasking, ss, vertex1); + const float mask_v2 = (1.0f - SCULPT_vertex_mask_get(ss, vertex2)) * + SCULPT_automasking_factor_get(automasking, ss, vertex2); float sim_location[3]; cloth_brush_simulation_location_get(ss, brush, sim_location); @@ -1129,15 +1135,17 @@ void SCULPT_cloth_brush_simulation_init(SculptSession *ss, SculptClothSimulation const bool has_deformation_pos = cloth_sim->deformation_pos != NULL; const bool has_softbody_pos = cloth_sim->softbody_pos != NULL; for (int i = 0; i < totverts; i++) { - copy_v3_v3(cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, i)); - copy_v3_v3(cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, i)); - copy_v3_v3(cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, i)); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + copy_v3_v3(cloth_sim->last_iteration_pos[i], SCULPT_vertex_co_get(ss, vertex)); + copy_v3_v3(cloth_sim->init_pos[i], SCULPT_vertex_co_get(ss, vertex)); + copy_v3_v3(cloth_sim->prev_pos[i], SCULPT_vertex_co_get(ss, vertex)); if (has_deformation_pos) { - copy_v3_v3(cloth_sim->deformation_pos[i], SCULPT_vertex_co_get(ss, i)); + copy_v3_v3(cloth_sim->deformation_pos[i], SCULPT_vertex_co_get(ss, vertex)); cloth_sim->deformation_strength[i] = 1.0f; } if (has_softbody_pos) { - copy_v3_v3(cloth_sim->softbody_pos[i], SCULPT_vertex_co_get(ss, i)); + copy_v3_v3(cloth_sim->softbody_pos[i], SCULPT_vertex_co_get(ss, vertex)); } } } @@ -1146,7 +1154,9 @@ void SCULPT_cloth_brush_store_simulation_state(SculptSession *ss, SculptClothSim { const int totverts = SCULPT_vertex_count_get(ss); for (int i = 0; i < totverts; i++) { - copy_v3_v3(cloth_sim->pos[i], SCULPT_vertex_co_get(ss, i)); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + copy_v3_v3(cloth_sim->pos[i], SCULPT_vertex_co_get(ss, vertex)); } } @@ -1427,13 +1437,13 @@ static void cloth_filter_apply_forces_task_cb(void *__restrict userdata, PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { float fade = vd.mask ? *vd.mask : 0.0f; - fade *= SCULPT_automasking_factor_get(ss->filter_cache->automasking, ss, vd.index); + fade *= SCULPT_automasking_factor_get(ss->filter_cache->automasking, ss, vd.vertex); fade = 1.0f - fade; float force[3] = {0.0f, 0.0f, 0.0f}; float disp[3], temp[3], transform[3][3]; if (ss->filter_cache->active_face_set != SCULPT_FACE_SET_NONE) { - if (!SCULPT_vertex_has_face_set(ss, vd.index, ss->filter_cache->active_face_set)) { + if (!SCULPT_vertex_has_face_set(ss, vd.vertex, ss->filter_cache->active_face_set)) { continue; } } @@ -1452,7 +1462,7 @@ static void cloth_filter_apply_forces_task_cb(void *__restrict userdata, break; case CLOTH_FILTER_INFLATE: { float normal[3]; - SCULPT_vertex_normal_get(ss, vd.index, normal); + SCULPT_vertex_normal_get(ss, vd.vertex, normal); mul_v3_v3fl(force, normal, fade * data->filter_strength); } break; case CLOTH_FILTER_EXPAND: @@ -1517,7 +1527,9 @@ static int sculpt_cloth_filter_modal(bContext *C, wmOperator *op, const wmEvent const int totverts = SCULPT_vertex_count_get(ss); for (int i = 0; i < totverts; i++) { - copy_v3_v3(ss->filter_cache->cloth_sim->pos[i], SCULPT_vertex_co_get(ss, i)); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + copy_v3_v3(ss->filter_cache->cloth_sim->pos[i], SCULPT_vertex_co_get(ss, vertex)); } SculptThreadedTaskData data = { diff --git a/source/blender/editors/sculpt_paint/sculpt_detail.c b/source/blender/editors/sculpt_paint/sculpt_detail.c index 00503087e39..ebbb0fa429e 100644 --- a/source/blender/editors/sculpt_paint/sculpt_detail.c +++ b/source/blender/editors/sculpt_paint/sculpt_detail.c @@ -174,13 +174,13 @@ static void sample_detail_voxel(bContext *C, ViewContext *vc, const int mval[2]) BKE_sculpt_update_object_for_edit(depsgraph, ob, true, false, false); /* Average the edge length of the connected edges to the active vertex. */ - int active_vertex = SCULPT_active_vertex_get(ss); + PBVHVertRef active_vertex = SCULPT_active_vertex_get(ss); const float *active_vertex_co = SCULPT_active_vertex_co_get(ss); float edge_length = 0.0f; int tot = 0; SculptVertexNeighborIter ni; SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, active_vertex, ni) { - edge_length += len_v3v3(active_vertex_co, SCULPT_vertex_co_get(ss, ni.index)); + edge_length += len_v3v3(active_vertex_co, SCULPT_vertex_co_get(ss, ni.vertex)); tot += 1; } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); @@ -578,14 +578,14 @@ static void dyntopo_detail_size_sample_from_surface(Object *ob, DyntopoDetailSizeEditCustomData *cd) { SculptSession *ss = ob->sculpt; - const int active_vertex = SCULPT_active_vertex_get(ss); + const PBVHVertRef active_vertex = SCULPT_active_vertex_get(ss); float len_accum = 0; int num_neighbors = 0; SculptVertexNeighborIter ni; SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, active_vertex, ni) { len_accum += len_v3v3(SCULPT_vertex_co_get(ss, active_vertex), - SCULPT_vertex_co_get(ss, ni.index)); + SCULPT_vertex_co_get(ss, ni.vertex)); num_neighbors++; } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c index 4f884420401..4f91d2215fb 100644 --- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c +++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c @@ -92,13 +92,16 @@ void SCULPT_dyntopo_node_layers_add(SculptSession *ss) { int cd_node_layer_index; - char layer_id[] = "_dyntopo_node_id"; + char node_vertex_id[] = "_dyntopo_vnode_id"; + char node_face_id[] = "_dyntopo_fnode_id"; + + cd_node_layer_index = CustomData_get_named_layer_index( + &ss->bm->vdata, CD_PROP_INT32, node_vertex_id); - cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->vdata, CD_PROP_INT32, layer_id); if (cd_node_layer_index == -1) { - BM_data_layer_add_named(ss->bm, &ss->bm->vdata, CD_PROP_INT32, layer_id); + BM_data_layer_add_named(ss->bm, &ss->bm->vdata, CD_PROP_INT32, node_vertex_id); cd_node_layer_index = CustomData_get_named_layer_index( - &ss->bm->vdata, CD_PROP_INT32, layer_id); + &ss->bm->vdata, CD_PROP_INT32, node_vertex_id); } ss->cd_vert_node_offset = CustomData_get_n_offset( @@ -108,11 +111,12 @@ void SCULPT_dyntopo_node_layers_add(SculptSession *ss) ss->bm->vdata.layers[cd_node_layer_index].flag |= CD_FLAG_TEMPORARY; - cd_node_layer_index = CustomData_get_named_layer_index(&ss->bm->pdata, CD_PROP_INT32, layer_id); + cd_node_layer_index = CustomData_get_named_layer_index( + &ss->bm->pdata, CD_PROP_INT32, node_face_id); if (cd_node_layer_index == -1) { - BM_data_layer_add_named(ss->bm, &ss->bm->pdata, CD_PROP_INT32, layer_id); + BM_data_layer_add_named(ss->bm, &ss->bm->pdata, CD_PROP_INT32, node_face_id); cd_node_layer_index = CustomData_get_named_layer_index( - &ss->bm->pdata, CD_PROP_INT32, layer_id); + &ss->bm->pdata, CD_PROP_INT32, node_face_id); } ss->cd_face_node_offset = CustomData_get_n_offset( diff --git a/source/blender/editors/sculpt_paint/sculpt_expand.c b/source/blender/editors/sculpt_paint/sculpt_expand.c index da2c346cf82..dd1c7a36c16 100644 --- a/source/blender/editors/sculpt_paint/sculpt_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_expand.c @@ -140,10 +140,12 @@ enum { */ static bool sculpt_expand_is_vert_in_active_component(SculptSession *ss, ExpandCache *expand_cache, - const int v) + const PBVHVertRef v) { + int v_i = BKE_pbvh_vertex_to_index(ss->pbvh, v); + for (int i = 0; i < EXPAND_SYMM_AREAS; i++) { - if (ss->vertex_info.connected_component[v] == expand_cache->active_connected_components[i]) { + if (ss->vertex_info.connected_component[v_i] == expand_cache->active_connected_components[i]) { return true; } } @@ -158,7 +160,7 @@ static bool sculpt_expand_is_face_in_active_component(SculptSession *ss, const int f) { const MLoop *loop = &ss->mloop[ss->mpoly[f].loopstart]; - return sculpt_expand_is_vert_in_active_component(ss, expand_cache, loop->v); + return sculpt_expand_is_vert_in_active_component(ss, expand_cache, BKE_pbvh_make_vref(loop->v)); } /** @@ -167,14 +169,16 @@ static bool sculpt_expand_is_face_in_active_component(SculptSession *ss, */ static float sculpt_expand_falloff_value_vertex_get(SculptSession *ss, ExpandCache *expand_cache, - const int v) + const PBVHVertRef v) { + int v_i = BKE_pbvh_vertex_to_index(ss->pbvh, v); + if (expand_cache->texture_distortion_strength == 0.0f) { - return expand_cache->vert_falloff[v]; + return expand_cache->vert_falloff[v_i]; } if (!expand_cache->brush->mtex.tex) { - return expand_cache->vert_falloff[v]; + return expand_cache->vert_falloff[v_i]; } float rgba[4]; @@ -184,7 +188,7 @@ static float sculpt_expand_falloff_value_vertex_get(SculptSession *ss, const float distortion = (avg - 0.5f) * expand_cache->texture_distortion_strength * expand_cache->max_vert_falloff; - return expand_cache->vert_falloff[v] + distortion; + return expand_cache->vert_falloff[v_i] + distortion; } /** @@ -209,7 +213,9 @@ static float sculpt_expand_max_vertex_falloff_get(ExpandCache *expand_cache) * Main function to get the state of a vertex for the current state and settings of a #ExpandCache. * Returns true when the target data should be modified by expand. */ -static bool sculpt_expand_state_get(SculptSession *ss, ExpandCache *expand_cache, const int v) +static bool sculpt_expand_state_get(SculptSession *ss, + ExpandCache *expand_cache, + const PBVHVertRef v) { if (!SCULPT_vertex_visible_get(ss, v)) { return false; @@ -303,7 +309,7 @@ static bool sculpt_expand_face_state_get(SculptSession *ss, ExpandCache *expand_ */ static float sculpt_expand_gradient_value_get(SculptSession *ss, ExpandCache *expand_cache, - const int v) + const PBVHVertRef v) { if (!expand_cache->falloff_gradient) { return 1.0f; @@ -347,7 +353,8 @@ static BLI_bitmap *sculpt_expand_bitmap_from_enabled(SculptSession *ss, ExpandCa const int totvert = SCULPT_vertex_count_get(ss); BLI_bitmap *enabled_vertices = BLI_BITMAP_NEW(totvert, "enabled vertices"); for (int i = 0; i < totvert; i++) { - const bool enabled = sculpt_expand_state_get(ss, expand_cache, i); + const bool enabled = sculpt_expand_state_get( + ss, expand_cache, BKE_pbvh_index_to_vertex(ss->pbvh, i)); BLI_BITMAP_SET(enabled_vertices, i, enabled); } return enabled_vertices; @@ -369,16 +376,18 @@ static BLI_bitmap *sculpt_expand_boundary_from_enabled(SculptSession *ss, continue; } + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + bool is_expand_boundary = false; SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { if (!BLI_BITMAP_TEST(enabled_vertices, ni.index)) { is_expand_boundary = true; } } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); - if (use_mesh_boundary && SCULPT_vertex_is_boundary(ss, i)) { + if (use_mesh_boundary && SCULPT_vertex_is_boundary(ss, vertex)) { is_expand_boundary = true; } @@ -394,12 +403,12 @@ static BLI_bitmap *sculpt_expand_boundary_from_enabled(SculptSession *ss, * Utility function to get the closet vertex after flipping an original vertex position based on * an symmetry pass iteration index. */ -static int sculpt_expand_get_vertex_index_for_symmetry_pass(Object *ob, - const char symm_it, - const int original_vertex) +static PBVHVertRef sculpt_expand_get_vertex_index_for_symmetry_pass( + Object *ob, const char symm_it, const PBVHVertRef original_vertex) { SculptSession *ss = ob->sculpt; - int symm_vertex = SCULPT_EXPAND_VERTEX_NONE; + PBVHVertRef symm_vertex = {SCULPT_EXPAND_VERTEX_NONE}; + if (symm_it == 0) { symm_vertex = original_vertex; } @@ -415,7 +424,7 @@ static int sculpt_expand_get_vertex_index_for_symmetry_pass(Object *ob, * Geodesic: Initializes the falloff with geodesic distances from the given active vertex, taking * symmetry into account. */ -static float *sculpt_expand_geodesic_falloff_create(Sculpt *sd, Object *ob, const int v) +static float *sculpt_expand_geodesic_falloff_create(Sculpt *sd, Object *ob, const PBVHVertRef v) { return SCULPT_geodesic_from_vertex_and_symm(sd, ob, v, FLT_MAX); } @@ -432,20 +441,23 @@ typedef struct ExpandFloodFillData { } ExpandFloodFillData; static bool expand_topology_floodfill_cb( - SculptSession *UNUSED(ss), int from_v, int to_v, bool is_duplicate, void *userdata) + SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata) { + int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); + int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); + ExpandFloodFillData *data = userdata; if (!is_duplicate) { - const float to_it = data->dists[from_v] + 1.0f; - data->dists[to_v] = to_it; + const float to_it = data->dists[from_v_i] + 1.0f; + data->dists[to_v_i] = to_it; } else { - data->dists[to_v] = data->dists[from_v]; + data->dists[to_v_i] = data->dists[from_v_i]; } return true; } -static float *sculpt_expand_topology_falloff_create(Sculpt *sd, Object *ob, const int v) +static float *sculpt_expand_topology_falloff_create(Sculpt *sd, Object *ob, const PBVHVertRef v) { SculptSession *ss = ob->sculpt; const int totvert = SCULPT_vertex_count_get(ss); @@ -470,23 +482,26 @@ static float *sculpt_expand_topology_falloff_create(Sculpt *sd, Object *ob, cons * This creates falloff patterns that follow and snap to the hard edges of the object. */ static bool mask_expand_normal_floodfill_cb( - SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata) + SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata) { + int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); + int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); + ExpandFloodFillData *data = userdata; if (!is_duplicate) { float current_normal[3], prev_normal[3]; SCULPT_vertex_normal_get(ss, to_v, current_normal); SCULPT_vertex_normal_get(ss, from_v, prev_normal); - const float from_edge_factor = data->edge_factor[from_v]; - data->edge_factor[to_v] = dot_v3v3(current_normal, prev_normal) * from_edge_factor; - data->dists[to_v] = dot_v3v3(data->original_normal, current_normal) * - powf(from_edge_factor, data->edge_sensitivity); - CLAMP(data->dists[to_v], 0.0f, 1.0f); + const float from_edge_factor = data->edge_factor[from_v_i]; + data->edge_factor[to_v_i] = dot_v3v3(current_normal, prev_normal) * from_edge_factor; + data->dists[to_v_i] = dot_v3v3(data->original_normal, current_normal) * + powf(from_edge_factor, data->edge_sensitivity); + CLAMP(data->dists[to_v_i], 0.0f, 1.0f); } else { /* PBVH_GRIDS duplicate handling. */ - data->edge_factor[to_v] = data->edge_factor[from_v]; - data->dists[to_v] = data->dists[from_v]; + data->edge_factor[to_v_i] = data->edge_factor[from_v_i]; + data->dists[to_v_i] = data->dists[from_v_i]; } return true; @@ -494,7 +509,7 @@ static bool mask_expand_normal_floodfill_cb( static float *sculpt_expand_normal_falloff_create(Sculpt *sd, Object *ob, - const int v, + const PBVHVertRef v, const float edge_sensitivity) { SculptSession *ss = ob->sculpt; @@ -520,9 +535,11 @@ static float *sculpt_expand_normal_falloff_create(Sculpt *sd, for (int repeat = 0; repeat < 2; repeat++) { for (int i = 0; i < totvert; i++) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + float avg = 0.0f; SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { avg += dists[ni.index]; } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); @@ -539,7 +556,7 @@ static float *sculpt_expand_normal_falloff_create(Sculpt *sd, * Spherical: Initializes the falloff based on the distance from a vertex, taking symmetry into * account. */ -static float *sculpt_expand_spherical_falloff_create(Object *ob, const int v) +static float *sculpt_expand_spherical_falloff_create(Object *ob, const PBVHVertRef v) { SculptSession *ss = ob->sculpt; const int totvert = SCULPT_vertex_count_get(ss); @@ -554,11 +571,14 @@ static float *sculpt_expand_spherical_falloff_create(Object *ob, const int v) if (!SCULPT_is_symmetry_iteration_valid(symm_it, symm)) { continue; } - const int symm_vertex = sculpt_expand_get_vertex_index_for_symmetry_pass(ob, symm_it, v); - if (symm_vertex != -1) { + const PBVHVertRef symm_vertex = sculpt_expand_get_vertex_index_for_symmetry_pass( + ob, symm_it, v); + if (symm_vertex.i != SCULPT_EXPAND_VERTEX_NONE) { const float *co = SCULPT_vertex_co_get(ss, symm_vertex); for (int i = 0; i < totvert; i++) { - dists[i] = min_ff(dists[i], len_v3v3(co, SCULPT_vertex_co_get(ss, i))); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + dists[i] = min_ff(dists[i], len_v3v3(co, SCULPT_vertex_co_get(ss, vertex))); } } } @@ -571,13 +591,13 @@ static float *sculpt_expand_spherical_falloff_create(Object *ob, const int v) * boundary to a falloff value of 0. Then, it propagates that falloff to the rest of the mesh so it * stays parallel to the boundary, increasing the falloff value by 1 on each step. */ -static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const int v) +static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const PBVHVertRef v) { SculptSession *ss = ob->sculpt; const int totvert = SCULPT_vertex_count_get(ss); float *dists = MEM_calloc_arrayN(totvert, sizeof(float), "spherical dist"); BLI_bitmap *visited_vertices = BLI_BITMAP_NEW(totvert, "visited vertices"); - GSQueue *queue = BLI_gsqueue_new(sizeof(int)); + GSQueue *queue = BLI_gsqueue_new(sizeof(PBVHVertRef)); /* Search and initialize a boundary per symmetry pass, then mark those vertices as visited. */ const char symm = SCULPT_mesh_symmetry_xyz_get(ob); @@ -586,7 +606,8 @@ static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const i continue; } - const int symm_vertex = sculpt_expand_get_vertex_index_for_symmetry_pass(ob, symm_it, v); + const PBVHVertRef symm_vertex = sculpt_expand_get_vertex_index_for_symmetry_pass( + ob, symm_it, v); SculptBoundary *boundary = SCULPT_boundary_data_init(ob, NULL, symm_vertex, FLT_MAX); if (!boundary) { @@ -595,7 +616,7 @@ static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const i for (int i = 0; i < boundary->num_vertices; i++) { BLI_gsqueue_push(queue, &boundary->vertices[i]); - BLI_BITMAP_ENABLE(visited_vertices, boundary->vertices[i]); + BLI_BITMAP_ENABLE(visited_vertices, boundary->vertices_i[i]); } SCULPT_boundary_data_free(boundary); } @@ -607,17 +628,19 @@ static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const i /* Propagate the values from the boundaries to the rest of the mesh. */ while (!BLI_gsqueue_is_empty(queue)) { - int v_next; + PBVHVertRef v_next; + BLI_gsqueue_pop(queue, &v_next); + int v_next_i = BKE_pbvh_vertex_to_index(ss->pbvh, v_next); SculptVertexNeighborIter ni; SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, v_next, ni) { if (BLI_BITMAP_TEST(visited_vertices, ni.index)) { continue; } - dists[ni.index] = dists[v_next] + 1.0f; + dists[ni.index] = dists[v_next_i] + 1.0f; BLI_BITMAP_ENABLE(visited_vertices, ni.index); - BLI_gsqueue_push(queue, &ni.index); + BLI_gsqueue_push(queue, &ni.vertex); } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); } @@ -632,7 +655,7 @@ static float *sculpt_expand_boundary_topology_falloff_create(Object *ob, const i * the base mesh faces when checking a vertex neighbor. For this reason, this is not implement * using the general flood-fill and sculpt neighbors accessors. */ -static float *sculpt_expand_diagonals_falloff_create(Object *ob, const int v) +static float *sculpt_expand_diagonals_falloff_create(Object *ob, const PBVHVertRef v) { SculptSession *ss = ob->sculpt; const int totvert = SCULPT_vertex_count_get(ss); @@ -647,17 +670,19 @@ static float *sculpt_expand_diagonals_falloff_create(Object *ob, const int v) /* Search and mask as visited the initial vertices using the enabled symmetry passes. */ BLI_bitmap *visited_vertices = BLI_BITMAP_NEW(totvert, "visited vertices"); - GSQueue *queue = BLI_gsqueue_new(sizeof(int)); + GSQueue *queue = BLI_gsqueue_new(sizeof(PBVHVertRef)); const char symm = SCULPT_mesh_symmetry_xyz_get(ob); for (char symm_it = 0; symm_it <= symm; symm_it++) { if (!SCULPT_is_symmetry_iteration_valid(symm_it, symm)) { continue; } - const int symm_vertex = sculpt_expand_get_vertex_index_for_symmetry_pass(ob, symm_it, v); + const PBVHVertRef symm_vertex = sculpt_expand_get_vertex_index_for_symmetry_pass( + ob, symm_it, v); + int symm_vertex_i = BKE_pbvh_vertex_to_index(ss->pbvh, symm_vertex); BLI_gsqueue_push(queue, &symm_vertex); - BLI_BITMAP_ENABLE(visited_vertices, symm_vertex); + BLI_BITMAP_ENABLE(visited_vertices, symm_vertex_i); } if (BLI_gsqueue_is_empty(queue)) { @@ -667,17 +692,20 @@ static float *sculpt_expand_diagonals_falloff_create(Object *ob, const int v) /* Propagate the falloff increasing the value by 1 each time a new vertex is visited. */ Mesh *mesh = ob->data; while (!BLI_gsqueue_is_empty(queue)) { - int v_next; + PBVHVertRef v_next; BLI_gsqueue_pop(queue, &v_next); - for (int j = 0; j < ss->pmap[v_next].count; j++) { - MPoly *p = &ss->mpoly[ss->pmap[v_next].indices[j]]; + + int v_next_i = BKE_pbvh_vertex_to_index(ss->pbvh, v_next); + + for (int j = 0; j < ss->pmap[v_next_i].count; j++) { + MPoly *p = &ss->mpoly[ss->pmap[v_next_i].indices[j]]; for (int l = 0; l < p->totloop; l++) { - const int neighbor_v = mesh->mloop[p->loopstart + l].v; - if (BLI_BITMAP_TEST(visited_vertices, neighbor_v)) { + const PBVHVertRef neighbor_v = BKE_pbvh_make_vref(mesh->mloop[p->loopstart + l].v); + if (BLI_BITMAP_TEST(visited_vertices, neighbor_v.i)) { continue; } - dists[neighbor_v] = dists[v_next] + 1.0f; - BLI_BITMAP_ENABLE(visited_vertices, neighbor_v); + dists[neighbor_v.i] = dists[v_next_i] + 1.0f; + BLI_BITMAP_ENABLE(visited_vertices, neighbor_v.i); BLI_gsqueue_push(queue, &neighbor_v); } } @@ -701,11 +729,13 @@ static void sculpt_expand_update_max_vert_falloff_value(SculptSession *ss, const int totvert = SCULPT_vertex_count_get(ss); expand_cache->max_vert_falloff = -FLT_MAX; for (int i = 0; i < totvert; i++) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + if (expand_cache->vert_falloff[i] == FLT_MAX) { continue; } - if (!sculpt_expand_is_vert_in_active_component(ss, expand_cache, i)) { + if (!sculpt_expand_is_vert_in_active_component(ss, expand_cache, vertex)) { continue; } @@ -856,7 +886,9 @@ static void sculpt_expand_topology_from_state_boundary(Object *ob, if (!BLI_BITMAP_TEST(boundary_vertices, i)) { continue; } - SCULPT_floodfill_add_and_skip_initial(&flood, i); + + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + SCULPT_floodfill_add_and_skip_initial(&flood, vertex); } MEM_freeN(boundary_vertices); @@ -921,10 +953,12 @@ static void sculpt_expand_initialize_from_face_set_boundary(Object *ob, BLI_bitmap *enabled_vertices = BLI_BITMAP_NEW(totvert, "enabled vertices"); for (int i = 0; i < totvert; i++) { - if (!SCULPT_vertex_has_unique_face_set(ss, i)) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + if (!SCULPT_vertex_has_unique_face_set(ss, vertex)) { continue; } - if (!SCULPT_vertex_has_face_set(ss, i, active_face_set)) { + if (!SCULPT_vertex_has_face_set(ss, vertex, active_face_set)) { continue; } BLI_BITMAP_ENABLE(enabled_vertices, i); @@ -941,8 +975,10 @@ static void sculpt_expand_initialize_from_face_set_boundary(Object *ob, if (internal_falloff) { for (int i = 0; i < totvert; i++) { - if (!(SCULPT_vertex_has_face_set(ss, i, active_face_set) && - SCULPT_vertex_has_unique_face_set(ss, i))) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + if (!(SCULPT_vertex_has_face_set(ss, vertex, active_face_set) && + SCULPT_vertex_has_unique_face_set(ss, vertex))) { continue; } expand_cache->vert_falloff[i] *= -1.0f; @@ -960,7 +996,9 @@ static void sculpt_expand_initialize_from_face_set_boundary(Object *ob, } else { for (int i = 0; i < totvert; i++) { - if (!SCULPT_vertex_has_face_set(ss, i, active_face_set)) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + if (!SCULPT_vertex_has_face_set(ss, vertex, active_face_set)) { continue; } expand_cache->vert_falloff[i] = 0.0f; @@ -976,7 +1014,7 @@ static void sculpt_expand_falloff_factors_from_vertex_and_symm_create( ExpandCache *expand_cache, Sculpt *sd, Object *ob, - const int v, + const PBVHVertRef v, eSculptExpandFalloffType falloff_type) { MEM_SAFE_FREE(expand_cache->vert_falloff); @@ -1128,7 +1166,7 @@ static void sculpt_expand_restore_color_data(SculptSession *ss, ExpandCache *exp PBVHNode *node = nodes[n]; PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { - SCULPT_vertex_color_set(ss, vd.index, expand_cache->original_colors[vd.index]); + SCULPT_vertex_color_set(ss, vd.vertex, expand_cache->original_colors[vd.index]); } BKE_pbvh_vertex_iter_end; BKE_pbvh_node_mark_redraw(node); @@ -1215,12 +1253,12 @@ static void sculpt_expand_mask_update_task_cb(void *__restrict userdata, PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_ALL) { const float initial_mask = *vd.mask; - const bool enabled = sculpt_expand_state_get(ss, expand_cache, vd.index); + const bool enabled = sculpt_expand_state_get(ss, expand_cache, vd.vertex); float new_mask; if (enabled) { - new_mask = sculpt_expand_gradient_value_get(ss, expand_cache, vd.index); + new_mask = sculpt_expand_gradient_value_get(ss, expand_cache, vd.vertex); } else { new_mask = 0.0f; @@ -1284,13 +1322,13 @@ static void sculpt_expand_colors_update_task_cb(void *__restrict userdata, PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_ALL) { float initial_color[4]; - SCULPT_vertex_color_get(ss, vd.index, initial_color); + SCULPT_vertex_color_get(ss, vd.vertex, initial_color); - const bool enabled = sculpt_expand_state_get(ss, expand_cache, vd.index); + const bool enabled = sculpt_expand_state_get(ss, expand_cache, vd.vertex); float fade; if (enabled) { - fade = sculpt_expand_gradient_value_get(ss, expand_cache, vd.index); + fade = sculpt_expand_gradient_value_get(ss, expand_cache, vd.vertex); } else { fade = 0.0f; @@ -1311,7 +1349,7 @@ static void sculpt_expand_colors_update_task_cb(void *__restrict userdata, continue; } - SCULPT_vertex_color_set(ss, vd.index, final_color); + SCULPT_vertex_color_set(ss, vd.vertex, final_color); any_changed = true; } @@ -1358,14 +1396,18 @@ static void sculpt_expand_original_state_store(Object *ob, ExpandCache *expand_c if (expand_cache->target == SCULPT_EXPAND_TARGET_MASK) { expand_cache->original_mask = MEM_malloc_arrayN(totvert, sizeof(float), "initial mask"); for (int i = 0; i < totvert; i++) { - expand_cache->original_mask[i] = SCULPT_vertex_mask_get(ss, i); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + expand_cache->original_mask[i] = SCULPT_vertex_mask_get(ss, vertex); } } if (expand_cache->target == SCULPT_EXPAND_TARGET_COLORS) { expand_cache->original_colors = MEM_malloc_arrayN(totvert, sizeof(float[4]), "initial colors"); for (int i = 0; i < totvert; i++) { - SCULPT_vertex_color_get(ss, i, expand_cache->original_colors[i]); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + SCULPT_vertex_color_get(ss, vertex, expand_cache->original_colors[i]); } } } @@ -1388,14 +1430,16 @@ static void sculpt_expand_face_sets_restore(SculptSession *ss, ExpandCache *expa } } -static void sculpt_expand_update_for_vertex(bContext *C, Object *ob, const int vertex) +static void sculpt_expand_update_for_vertex(bContext *C, Object *ob, const PBVHVertRef vertex) { SculptSession *ss = ob->sculpt; Sculpt *sd = CTX_data_tool_settings(C)->sculpt; ExpandCache *expand_cache = ss->expand_cache; + int vertex_i = BKE_pbvh_vertex_to_index(ss->pbvh, vertex); + /* Update the active factor in the cache. */ - if (vertex == SCULPT_EXPAND_VERTEX_NONE) { + if (vertex.i == SCULPT_EXPAND_VERTEX_NONE) { /* This means that the cursor is not over the mesh, so a valid active falloff can't be * determined. In this situations, don't evaluate enabled states and default all vertices in * connected components to enabled. */ @@ -1403,7 +1447,7 @@ static void sculpt_expand_update_for_vertex(bContext *C, Object *ob, const int v expand_cache->all_enabled = true; } else { - expand_cache->active_falloff = expand_cache->vert_falloff[vertex]; + expand_cache->active_falloff = expand_cache->vert_falloff[vertex_i]; expand_cache->all_enabled = false; } @@ -1444,14 +1488,16 @@ static void sculpt_expand_update_for_vertex(bContext *C, Object *ob, const int v * Updates the #SculptSession cursor data and gets the active vertex * if the cursor is over the mesh. */ -static int sculpt_expand_target_vertex_update_and_get(bContext *C, Object *ob, const float mval[2]) +static PBVHVertRef sculpt_expand_target_vertex_update_and_get(bContext *C, + Object *ob, + const float mval[2]) { SculptSession *ss = ob->sculpt; SculptCursorGeometryInfo sgi; if (SCULPT_cursor_geometry_info_update(C, &sgi, mval, false)) { return SCULPT_active_vertex_get(ss); } - return SCULPT_EXPAND_VERTEX_NONE; + return BKE_pbvh_make_vref(SCULPT_EXPAND_VERTEX_NONE); } /** @@ -1487,15 +1533,17 @@ static void sculpt_expand_reposition_pivot(bContext *C, Object *ob, ExpandCache const float *expand_init_co = SCULPT_vertex_co_get(ss, expand_cache->initial_active_vertex); for (int i = 0; i < totvert; i++) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + if (!BLI_BITMAP_TEST(boundary_vertices, i)) { continue; } - if (!sculpt_expand_is_vert_in_active_component(ss, expand_cache, i)) { + if (!sculpt_expand_is_vert_in_active_component(ss, expand_cache, vertex)) { continue; } - const float *vertex_co = SCULPT_vertex_co_get(ss, i); + const float *vertex_co = SCULPT_vertex_co_get(ss, vertex); if (!SCULPT_check_vertex_pivot_symmetry(vertex_co, expand_init_co, symm)) { continue; @@ -1550,9 +1598,8 @@ static void sculpt_expand_finish(bContext *C) * Finds and stores in the #ExpandCache the sculpt connected component index for each symmetry pass * needed for expand. */ -static void sculpt_expand_find_active_connected_components_from_vert(Object *ob, - ExpandCache *expand_cache, - const int initial_vertex) +static void sculpt_expand_find_active_connected_components_from_vert( + Object *ob, ExpandCache *expand_cache, const PBVHVertRef initial_vertex) { SculptSession *ss = ob->sculpt; for (int i = 0; i < EXPAND_SYMM_AREAS; i++) { @@ -1565,11 +1612,13 @@ static void sculpt_expand_find_active_connected_components_from_vert(Object *ob, continue; } - const int symm_vertex = sculpt_expand_get_vertex_index_for_symmetry_pass( + const PBVHVertRef symm_vertex = sculpt_expand_get_vertex_index_for_symmetry_pass( ob, symm_it, initial_vertex); + int symm_vertex_i = BKE_pbvh_vertex_to_index(ss->pbvh, symm_vertex); + expand_cache->active_connected_components[(int)symm_it] = - ss->vertex_info.connected_component[symm_vertex]; + ss->vertex_info.connected_component[symm_vertex_i]; } } @@ -1583,14 +1632,20 @@ static void sculpt_expand_set_initial_components_for_mouse(bContext *C, const float mval[2]) { SculptSession *ss = ob->sculpt; - int initial_vertex = sculpt_expand_target_vertex_update_and_get(C, ob, mval); - if (initial_vertex == SCULPT_EXPAND_VERTEX_NONE) { + + PBVHVertRef initial_vertex = sculpt_expand_target_vertex_update_and_get(C, ob, mval); + + if (initial_vertex.i == SCULPT_EXPAND_VERTEX_NONE) { /* Cursor not over the mesh, for creating valid initial falloffs, fallback to the last active * vertex in the sculpt session. */ initial_vertex = SCULPT_active_vertex_get(ss); } + + int initial_vertex_i = BKE_pbvh_vertex_to_index(ss->pbvh, initial_vertex); + copy_v2_v2(ss->expand_cache->initial_mouse, mval); expand_cache->initial_active_vertex = initial_vertex; + expand_cache->initial_active_vertex_i = initial_vertex_i; expand_cache->initial_active_face_set = SCULPT_active_face_set_get(ss); if (expand_cache->next_face_set == SCULPT_FACE_SET_NONE) { @@ -1690,7 +1745,8 @@ static int sculpt_expand_modal(bContext *C, wmOperator *op, const wmEvent *event /* Update and get the active vertex (and face) from the cursor. */ const float mval_fl[2] = {UNPACK2(event->mval)}; - const int target_expand_vertex = sculpt_expand_target_vertex_update_and_get(C, ob, mval_fl); + const PBVHVertRef target_expand_vertex = sculpt_expand_target_vertex_update_and_get( + C, ob, mval_fl); /* Handle the modal keymap state changes. */ ExpandCache *expand_cache = ss->expand_cache; diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c index 91763a15e37..f045ba841f3 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.c +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c @@ -142,7 +142,7 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); if (fade > 0.05f && ss->face_sets[vert_map->indices[j]] > 0) { @@ -161,11 +161,11 @@ static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); if (fade > 0.05f) { - SCULPT_vertex_face_set_set(ss, vd.index, ss->cache->paint_face_set); + SCULPT_vertex_face_set_set(ss, vd.vertex, ss->cache->paint_face_set); } } } @@ -199,7 +199,7 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata, if (!sculpt_brush_test_sq_fn(&test, vd.co)) { continue; } - if (relax_face_sets == SCULPT_vertex_has_unique_face_set(ss, vd.index)) { + if (relax_face_sets == SCULPT_vertex_has_unique_face_set(ss, vd.vertex)) { continue; } @@ -210,12 +210,12 @@ static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); SCULPT_relax_vertex(ss, &vd, fade * bstrength, relax_face_sets, vd.co); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -324,8 +324,11 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op) if (mode == SCULPT_FACE_SET_MASKED) { for (int i = 0; i < tot_vert; i++) { - if (SCULPT_vertex_mask_get(ss, i) >= threshold && SCULPT_vertex_visible_get(ss, i)) { - SCULPT_vertex_face_set_set(ss, i, next_face_set); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + if (SCULPT_vertex_mask_get(ss, vertex) >= threshold && + SCULPT_vertex_visible_get(ss, vertex)) { + SCULPT_vertex_face_set_set(ss, vertex, next_face_set); } } } @@ -337,7 +340,9 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op) * sets and the performance hit of rendering the overlay. */ bool all_visible = true; for (int i = 0; i < tot_vert; i++) { - if (!SCULPT_vertex_visible_get(ss, i)) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + if (!SCULPT_vertex_visible_get(ss, vertex)) { all_visible = false; break; } @@ -351,15 +356,19 @@ static int sculpt_face_set_create_exec(bContext *C, wmOperator *op) } for (int i = 0; i < tot_vert; i++) { - if (SCULPT_vertex_visible_get(ss, i)) { - SCULPT_vertex_face_set_set(ss, i, next_face_set); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + if (SCULPT_vertex_visible_get(ss, vertex)) { + SCULPT_vertex_face_set_set(ss, vertex, next_face_set); } } } if (mode == SCULPT_FACE_SET_ALL) { for (int i = 0; i < tot_vert; i++) { - SCULPT_vertex_face_set_set(ss, i, next_face_set); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + SCULPT_vertex_face_set_set(ss, vertex, next_face_set); } } @@ -869,7 +878,9 @@ static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op) * be synced from face sets to non-manifold vertices. */ if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) { for (int i = 0; i < tot_vert; i++) { - if (!SCULPT_vertex_visible_get(ss, i)) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + if (!SCULPT_vertex_visible_get(ss, vertex)) { hidden_vertex = true; break; } @@ -1222,9 +1233,11 @@ static void sculpt_face_set_edit_fair_face_set(Object *ob, SCULPT_boundary_info_ensure(ob); for (int i = 0; i < totvert; i++) { - fair_vertices[i] = !SCULPT_vertex_is_boundary(ss, i) && - SCULPT_vertex_has_face_set(ss, i, active_face_set_id) && - SCULPT_vertex_has_unique_face_set(ss, i); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + fair_vertices[i] = !SCULPT_vertex_is_boundary(ss, vertex) && + SCULPT_vertex_has_face_set(ss, vertex, active_face_set_id) && + SCULPT_vertex_has_unique_face_set(ss, vertex); } MVert *mvert = SCULPT_mesh_deformed_mverts_get(ss); diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_color.c b/source/blender/editors/sculpt_paint/sculpt_filter_color.c index 27092bf9a04..7a1e08ea713 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_color.c @@ -104,7 +104,7 @@ static void color_filter_task_cb(void *__restrict userdata, float fade = vd.mask ? *vd.mask : 0.0f; fade = 1.0f - fade; fade *= data->filter_strength; - fade *= SCULPT_automasking_factor_get(ss->filter_cache->automasking, ss, vd.index); + fade *= SCULPT_automasking_factor_get(ss->filter_cache->automasking, ss, vd.vertex); if (fade == 0.0f) { continue; } @@ -189,10 +189,10 @@ static void color_filter_task_cb(void *__restrict userdata, case COLOR_FILTER_SMOOTH: { fade = clamp_f(fade, -1.0f, 1.0f); float smooth_color[4]; - SCULPT_neighbor_color_average(ss, smooth_color, vd.index); + SCULPT_neighbor_color_average(ss, smooth_color, vd.vertex); float col[4]; - SCULPT_vertex_color_get(ss, vd.index, col); + SCULPT_vertex_color_get(ss, vd.vertex, col); if (fade < 0.0f) { interp_v4_v4v4(smooth_color, smooth_color, col, 0.5f); @@ -224,7 +224,7 @@ static void color_filter_task_cb(void *__restrict userdata, } } - SCULPT_vertex_color_set(ss, vd.index, final_color); + SCULPT_vertex_color_set(ss, vd.vertex, final_color); } BKE_pbvh_vertex_iter_end; BKE_pbvh_node_mark_update_color(data->nodes[n]); @@ -240,7 +240,8 @@ static void sculpt_color_presmooth_init(SculptSession *ss) } for (int i = 0; i < totvert; i++) { - SCULPT_vertex_color_get(ss, i, ss->filter_cache->pre_smoothed_color[i]); + SCULPT_vertex_color_get( + ss, BKE_pbvh_index_to_vertex(ss->pbvh, i), ss->filter_cache->pre_smoothed_color[i]); } for (int iteration = 0; iteration < 2; iteration++) { @@ -249,7 +250,7 @@ static void sculpt_color_presmooth_init(SculptSession *ss) int total = 0; SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, BKE_pbvh_index_to_vertex(ss->pbvh, i), ni) { float col[4] = {0}; copy_v4_v4(col, ss->filter_cache->pre_smoothed_color[ni.index]); diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c index a21656435a3..fa4fe191273 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mask.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mask.c @@ -103,7 +103,7 @@ static void mask_filter_task_cb(void *__restrict userdata, switch (mode) { case MASK_FILTER_SMOOTH: case MASK_FILTER_SHARPEN: { - float val = SCULPT_neighbor_mask_average(ss, vd.index); + float val = SCULPT_neighbor_mask_average(ss, vd.vertex); val -= *vd.mask; @@ -123,7 +123,7 @@ static void mask_filter_task_cb(void *__restrict userdata, } case MASK_FILTER_GROW: max = 0.0f; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) { float vmask_f = data->prev_mask[ni.index]; if (vmask_f > max) { max = vmask_f; @@ -134,7 +134,7 @@ static void mask_filter_task_cb(void *__restrict userdata, break; case MASK_FILTER_SHRINK: min = 1.0f; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) { float vmask_f = data->prev_mask[ni.index]; if (vmask_f < min) { min = vmask_f; @@ -214,7 +214,8 @@ static int sculpt_mask_filter_exec(bContext *C, wmOperator *op) if (ELEM(filter_type, MASK_FILTER_GROW, MASK_FILTER_SHRINK)) { prev_mask = MEM_mallocN(num_verts * sizeof(float), "prevmask"); for (int j = 0; j < num_verts; j++) { - prev_mask[j] = SCULPT_vertex_mask_get(ss, j); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, j); + prev_mask[j] = SCULPT_vertex_mask_get(ss, vertex); } } @@ -305,9 +306,9 @@ static float neighbor_dirty_mask(SculptSession *ss, PBVHVertexIter *vd) zero_v3(avg); SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd->index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd->vertex, ni) { float normalized[3]; - sub_v3_v3v3(normalized, SCULPT_vertex_co_get(ss, ni.index), vd->co); + sub_v3_v3v3(normalized, SCULPT_vertex_co_get(ss, ni.vertex), vd->co); normalize_v3(normalized); add_v3_v3(avg, normalized); total++; diff --git a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c index 9e84d9ac65d..4f45b7917ec 100644 --- a/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c +++ b/source/blender/editors/sculpt_paint/sculpt_filter_mesh.c @@ -296,7 +296,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, float fade = vd.mask ? *vd.mask : 0.0f; fade = 1.0f - fade; fade *= data->filter_strength; - fade *= SCULPT_automasking_factor_get(ss->filter_cache->automasking, ss, vd.index); + fade *= SCULPT_automasking_factor_get(ss->filter_cache->automasking, ss, vd.vertex); if (fade == 0.0f && filter_type != MESH_FILTER_SURFACE_SMOOTH) { /* Surface Smooth can't skip the loop for this vertex as it needs to calculate its @@ -314,7 +314,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, } if (filter_type == MESH_FILTER_RELAX_FACE_SETS) { - if (relax_face_sets == SCULPT_vertex_has_unique_face_set(ss, vd.index)) { + if (relax_face_sets == SCULPT_vertex_has_unique_face_set(ss, vd.vertex)) { continue; } } @@ -322,7 +322,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, switch (filter_type) { case MESH_FILTER_SMOOTH: fade = clamp_f(fade, -1.0f, 1.0f); - SCULPT_neighbor_coords_average_interior(ss, avg, vd.index); + SCULPT_neighbor_coords_average_interior(ss, avg, vd.vertex); sub_v3_v3v3(val, avg, orig_co); madd_v3_v3v3fl(val, orig_co, val, fade); sub_v3_v3v3(disp, val, orig_co); @@ -385,7 +385,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, disp, vd.co, ss->filter_cache->surface_smooth_laplacian_disp, - vd.index, + vd.vertex, orig_data.co, ss->filter_cache->surface_smooth_shape_preservation); break; @@ -399,10 +399,10 @@ static void mesh_filter_task_cb(void *__restrict userdata, float disp_sharpen[3] = {0.0f, 0.0f, 0.0f}; SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) { float disp_n[3]; sub_v3_v3v3( - disp_n, SCULPT_vertex_co_get(ss, ni.index), SCULPT_vertex_co_get(ss, vd.index)); + disp_n, SCULPT_vertex_co_get(ss, ni.vertex), SCULPT_vertex_co_get(ss, vd.vertex)); mul_v3_fl(disp_n, ss->filter_cache->sharpen_factor[ni.index]); add_v3_v3(disp_sharpen, disp_n); } @@ -412,7 +412,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, float disp_avg[3]; float avg_co[3]; - SCULPT_neighbor_coords_average(ss, avg_co, vd.index); + SCULPT_neighbor_coords_average(ss, avg_co, vd.vertex); sub_v3_v3v3(disp_avg, avg_co, vd.co); mul_v3_v3fl( disp_avg, disp_avg, smooth_ratio * pow2f(ss->filter_cache->sharpen_factor[vd.index])); @@ -457,7 +457,7 @@ static void mesh_filter_task_cb(void *__restrict userdata, } copy_v3_v3(vd.co, final_pos); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -473,9 +473,11 @@ static void mesh_filter_enhance_details_init_directions(SculptSession *ss) filter_cache->detail_directions = MEM_malloc_arrayN( totvert, sizeof(float[3]), "detail directions"); for (int i = 0; i < totvert; i++) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + float avg[3]; - SCULPT_neighbor_coords_average(ss, avg, i); - sub_v3_v3v3(filter_cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i)); + SCULPT_neighbor_coords_average(ss, avg, vertex); + sub_v3_v3v3(filter_cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, vertex)); } } @@ -500,7 +502,9 @@ static void mesh_filter_init_limit_surface_co(SculptSession *ss) filter_cache->limit_surface_co = MEM_malloc_arrayN( totvert, sizeof(float[3]), "limit surface co"); for (int i = 0; i < totvert; i++) { - SCULPT_vertex_limit_surface_get(ss, i, filter_cache->limit_surface_co[i]); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + SCULPT_vertex_limit_surface_get(ss, vertex, filter_cache->limit_surface_co[i]); } } @@ -520,9 +524,11 @@ static void mesh_filter_sharpen_init(SculptSession *ss, totvert, sizeof(float[3]), "sharpen detail direction"); for (int i = 0; i < totvert; i++) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + float avg[3]; - SCULPT_neighbor_coords_average(ss, avg, i); - sub_v3_v3v3(filter_cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i)); + SCULPT_neighbor_coords_average(ss, avg, vertex); + sub_v3_v3v3(filter_cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, vertex)); filter_cache->sharpen_factor[i] = len_v3(filter_cache->detail_directions[i]); } @@ -544,12 +550,14 @@ static void mesh_filter_sharpen_init(SculptSession *ss, smooth_iterations < filter_cache->sharpen_curvature_smooth_iterations; smooth_iterations++) { for (int i = 0; i < totvert; i++) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + float direction_avg[3] = {0.0f, 0.0f, 0.0f}; float sharpen_avg = 0; int total = 0; SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { add_v3_v3(direction_avg, filter_cache->detail_directions[ni.index]); sharpen_avg += filter_cache->sharpen_factor[ni.index]; total++; @@ -576,7 +584,7 @@ static void mesh_filter_surface_smooth_displace_task_cb( float fade = vd.mask ? *vd.mask : 0.0f; fade = 1.0f - fade; fade *= data->filter_strength; - fade *= SCULPT_automasking_factor_get(ss->filter_cache->automasking, ss, vd.index); + fade *= SCULPT_automasking_factor_get(ss->filter_cache->automasking, ss, vd.vertex); if (fade == 0.0f) { continue; } @@ -584,7 +592,7 @@ static void mesh_filter_surface_smooth_displace_task_cb( SCULPT_surface_smooth_displace_step(ss, vd.co, ss->filter_cache->surface_smooth_laplacian_disp, - vd.index, + vd.vertex, ss->filter_cache->surface_smooth_current_vertex, clamp_f(fade, 0.0f, 1.0f)); } diff --git a/source/blender/editors/sculpt_paint/sculpt_geodesic.c b/source/blender/editors/sculpt_paint/sculpt_geodesic.c index 1beb5d48961..ecf8c4586ae 100644 --- a/source/blender/editors/sculpt_paint/sculpt_geodesic.c +++ b/source/blender/editors/sculpt_paint/sculpt_geodesic.c @@ -279,9 +279,12 @@ static float *SCULPT_geodesic_fallback_create(Object *ob, GSet *initial_vertices return dists; } - const float *first_affected_co = SCULPT_vertex_co_get(ss, first_affected); + const float *first_affected_co = SCULPT_vertex_co_get( + ss, BKE_pbvh_index_to_vertex(ss->pbvh, first_affected)); for (int i = 0; i < totvert; i++) { - dists[i] = len_v3v3(first_affected_co, SCULPT_vertex_co_get(ss, i)); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + dists[i] = len_v3v3(first_affected_co, SCULPT_vertex_co_get(ss, vertex)); } return dists; @@ -305,7 +308,7 @@ float *SCULPT_geodesic_distances_create(Object *ob, float *SCULPT_geodesic_from_vertex_and_symm(Sculpt *sd, Object *ob, - const int vertex, + const PBVHVertRef vertex, const float limit_radius) { SculptSession *ss = ob->sculpt; @@ -314,7 +317,8 @@ float *SCULPT_geodesic_from_vertex_and_symm(Sculpt *sd, const char symm = SCULPT_mesh_symmetry_xyz_get(ob); for (char i = 0; i <= symm; ++i) { if (SCULPT_is_symmetry_iteration_valid(i, symm)) { - int v = -1; + PBVHVertRef v = {PBVH_REF_NONE}; + if (i == 0) { v = vertex; } @@ -323,8 +327,8 @@ float *SCULPT_geodesic_from_vertex_and_symm(Sculpt *sd, flip_v3_v3(location, SCULPT_vertex_co_get(ss, vertex), i); v = SCULPT_nearest_vertex_get(sd, ob, location, FLT_MAX, false); } - if (v != -1) { - BLI_gset_add(initial_vertices, POINTER_FROM_INT(v)); + if (v.i != PBVH_REF_NONE) { + BLI_gset_add(initial_vertices, POINTER_FROM_INT(BKE_pbvh_vertex_to_index(ss->pbvh, v))); } } } @@ -334,10 +338,11 @@ float *SCULPT_geodesic_from_vertex_and_symm(Sculpt *sd, return dists; } -float *SCULPT_geodesic_from_vertex(Object *ob, const int vertex, const float limit_radius) +float *SCULPT_geodesic_from_vertex(Object *ob, const PBVHVertRef vertex, const float limit_radius) { GSet *initial_vertices = BLI_gset_int_new("initial_vertices"); - BLI_gset_add(initial_vertices, POINTER_FROM_INT(vertex)); + BLI_gset_add(initial_vertices, + POINTER_FROM_INT(BKE_pbvh_vertex_to_index(ob->sculpt->pbvh, vertex))); float *dists = SCULPT_geodesic_distances_create(ob, initial_vertices, limit_radius); BLI_gset_free(initial_vertices, NULL); return dists; diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 166504ca8a9..6a10f7cad18 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -59,10 +59,13 @@ typedef struct SculptCursorGeometryInfo { typedef struct SculptVertexNeighborIter { /* Storage */ - int *neighbors; + PBVHVertRef *neighbors; + int *neighbor_indices; int size; int capacity; - int neighbors_fixed[SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY]; + + PBVHVertRef neighbors_fixed[SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY]; + int neighbor_indices_fixed[SCULPT_VERTEX_NEIGHBOR_FIXED_CAPACITY]; /* Internal iterator. */ int num_duplicates; @@ -70,6 +73,7 @@ typedef struct SculptVertexNeighborIter { /* Public */ int index; + PBVHVertRef vertex; bool is_duplicate; } SculptVertexNeighborIter; @@ -318,7 +322,7 @@ typedef struct SculptThreadedTaskData { bool mask_by_color_preserve_mask; /* Index of the vertex that is going to be used as a reference for the colors. */ - int mask_by_color_vertex; + PBVHVertRef mask_by_color_vertex; float *mask_by_color_floodfill; int face_set; @@ -691,7 +695,8 @@ typedef struct ExpandCache { * during the execution of Expand by moving the origin. */ float initial_mouse_move[2]; float initial_mouse[2]; - int initial_active_vertex; + PBVHVertRef initial_active_vertex; + int initial_active_vertex_i; int initial_active_face_set; /* Maximum number of vertices allowed in the SculptSession for previewing the falloff using @@ -899,14 +904,14 @@ bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(struct StrokeCache *cach void SCULPT_vertex_random_access_ensure(struct SculptSession *ss); int SCULPT_vertex_count_get(struct SculptSession *ss); -const float *SCULPT_vertex_co_get(struct SculptSession *ss, int index); +const float *SCULPT_vertex_co_get(struct SculptSession *ss, PBVHVertRef vertex); /** Get the normal for a given sculpt vertex; do not modify the result */ -void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3]); +void SCULPT_vertex_normal_get(SculptSession *ss, PBVHVertRef vertex, float no[3]); -float SCULPT_vertex_mask_get(struct SculptSession *ss, int index); -void SCULPT_vertex_color_get(const SculptSession *ss, int index, float r_color[4]); -void SCULPT_vertex_color_set(SculptSession *ss, int index, const float color[4]); +float SCULPT_vertex_mask_get(struct SculptSession *ss, PBVHVertRef vertex); +void SCULPT_vertex_color_get(const SculptSession *ss, PBVHVertRef vertex, float r_color[4]); +void SCULPT_vertex_color_set(SculptSession *ss, PBVHVertRef vertex, const float color[4]); /** Returns true if a color attribute exists in the current sculpt session. */ bool SCULPT_has_colors(const SculptSession *ss); @@ -914,19 +919,19 @@ bool SCULPT_has_colors(const SculptSession *ss); /** Returns true if the active color attribute is on loop (ATTR_DOMAIN_CORNER) domain. */ bool SCULPT_has_loop_colors(const struct Object *ob); -const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, int index); -void SCULPT_vertex_persistent_normal_get(SculptSession *ss, int index, float no[3]); +const float *SCULPT_vertex_persistent_co_get(SculptSession *ss, PBVHVertRef vertex); +void SCULPT_vertex_persistent_normal_get(SculptSession *ss, PBVHVertRef vertex, float no[3]); /** * Coordinates used for manipulating the base mesh when Grab Active Vertex is enabled. */ -const float *SCULPT_vertex_co_for_grab_active_get(SculptSession *ss, int index); +const float *SCULPT_vertex_co_for_grab_active_get(SculptSession *ss, PBVHVertRef vertex); /** * Returns the info of the limit surface when multi-res is available, * otherwise it returns the current coordinate of the vertex. */ -void SCULPT_vertex_limit_surface_get(SculptSession *ss, int index, float r_co[3]); +void SCULPT_vertex_limit_surface_get(SculptSession *ss, PBVHVertRef vertex, float r_co[3]); /** * Returns the pointer to the coordinates that should be edited from a brush tool iterator @@ -937,7 +942,7 @@ float *SCULPT_brush_deform_target_vertex_co_get(SculptSession *ss, PBVHVertexIter *iter); void SCULPT_vertex_neighbors_get(struct SculptSession *ss, - int index, + PBVHVertRef vertex, bool include_duplicates, SculptVertexNeighborIter *iter); @@ -946,7 +951,8 @@ void SCULPT_vertex_neighbors_get(struct SculptSession *ss, SCULPT_vertex_neighbors_get(ss, v_index, false, &neighbor_iterator); \ for (neighbor_iterator.i = 0; neighbor_iterator.i < neighbor_iterator.size; \ neighbor_iterator.i++) { \ - neighbor_iterator.index = neighbor_iterator.neighbors[neighbor_iterator.i]; + neighbor_iterator.vertex = neighbor_iterator.neighbors[neighbor_iterator.i]; \ + neighbor_iterator.index = neighbor_iterator.neighbor_indices[neighbor_iterator.i]; /** Iterate over neighboring and duplicate vertices (for PBVH_GRIDS). Duplicates come * first since they are nearest for floodfill. */ @@ -954,7 +960,8 @@ void SCULPT_vertex_neighbors_get(struct SculptSession *ss, SCULPT_vertex_neighbors_get(ss, v_index, true, &neighbor_iterator); \ for (neighbor_iterator.i = neighbor_iterator.size - 1; neighbor_iterator.i >= 0; \ neighbor_iterator.i--) { \ - neighbor_iterator.index = neighbor_iterator.neighbors[neighbor_iterator.i]; \ + neighbor_iterator.vertex = neighbor_iterator.neighbors[neighbor_iterator.i]; \ + neighbor_iterator.index = neighbor_iterator.neighbor_indices[neighbor_iterator.i]; \ neighbor_iterator.is_duplicate = (neighbor_iterator.i >= \ neighbor_iterator.size - neighbor_iterator.num_duplicates); @@ -965,7 +972,7 @@ void SCULPT_vertex_neighbors_get(struct SculptSession *ss, } \ ((void)0) -int SCULPT_active_vertex_get(SculptSession *ss); +PBVHVertRef SCULPT_active_vertex_get(SculptSession *ss); const float *SCULPT_active_vertex_co_get(SculptSession *ss); void SCULPT_active_vertex_normal_get(SculptSession *ss, float normal[3]); @@ -985,7 +992,7 @@ void SCULPT_fake_neighbors_free(struct Object *ob); /* Vertex Info. */ void SCULPT_boundary_info_ensure(Object *object); /* Boundary Info needs to be initialized in order to use this function. */ -bool SCULPT_vertex_is_boundary(const SculptSession *ss, int index); +bool SCULPT_vertex_is_boundary(const SculptSession *ss, PBVHVertRef vertex); void SCULPT_connected_components_ensure(Object *ob); @@ -995,8 +1002,8 @@ void SCULPT_connected_components_ensure(Object *ob); /** \name Sculpt Visibility API * \{ */ -void SCULPT_vertex_visible_set(SculptSession *ss, int index, bool visible); -bool SCULPT_vertex_visible_get(SculptSession *ss, int index); +void SCULPT_vertex_visible_set(SculptSession *ss, PBVHVertRef vertex, bool visible); +bool SCULPT_vertex_visible_get(SculptSession *ss, PBVHVertRef vertex); void SCULPT_visibility_sync_all_face_sets_to_vertices(struct Object *ob); void SCULPT_visibility_sync_all_vertex_to_face_sets(struct SculptSession *ss); @@ -1008,17 +1015,17 @@ void SCULPT_visibility_sync_all_vertex_to_face_sets(struct SculptSession *ss); * \{ */ int SCULPT_active_face_set_get(SculptSession *ss); -int SCULPT_vertex_face_set_get(SculptSession *ss, int index); -void SCULPT_vertex_face_set_set(SculptSession *ss, int index, int face_set); +int SCULPT_vertex_face_set_get(SculptSession *ss, PBVHVertRef vertex); +void SCULPT_vertex_face_set_set(SculptSession *ss, PBVHVertRef vertex, int face_set); -bool SCULPT_vertex_has_face_set(SculptSession *ss, int index, int face_set); -bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, int index); +bool SCULPT_vertex_has_face_set(SculptSession *ss, PBVHVertRef vertex, int face_set); +bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, PBVHVertRef vertex); int SCULPT_face_set_next_available_get(SculptSession *ss); void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visible); -bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, int index); -bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, int index); +bool SCULPT_vertex_all_face_sets_visible_get(const SculptSession *ss, PBVHVertRef vertex); +bool SCULPT_vertex_any_face_set_visible_get(SculptSession *ss, PBVHVertRef vertex); void SCULPT_face_sets_visibility_invert(SculptSession *ss); void SCULPT_face_sets_visibility_all_set(SculptSession *ss, bool visible); @@ -1104,11 +1111,11 @@ void SCULPT_calc_area_normal_and_center( void SCULPT_calc_area_center( Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float r_area_co[3]); -int SCULPT_nearest_vertex_get(struct Sculpt *sd, - struct Object *ob, - const float co[3], - float max_distance, - bool use_original); +PBVHVertRef SCULPT_nearest_vertex_get(struct Sculpt *sd, + struct Object *ob, + const float co[3], + float max_distance, + bool use_original); int SCULPT_plane_point_side(const float co[3], const float plane[4]); int SCULPT_plane_trim(const struct StrokeCache *cache, @@ -1187,7 +1194,7 @@ float SCULPT_brush_strength_factor(struct SculptSession *ss, const float vno[3], const float fno[3], float mask, - int vertex_index, + const PBVHVertRef vertex, int thread_id); /** @@ -1218,15 +1225,18 @@ void SCULPT_floodfill_add_initial_with_symmetry(struct Sculpt *sd, struct Object *ob, struct SculptSession *ss, SculptFloodFill *flood, - int index, + PBVHVertRef vertex, float radius); -void SCULPT_floodfill_add_initial(SculptFloodFill *flood, int index); -void SCULPT_floodfill_add_and_skip_initial(SculptFloodFill *flood, int index); -void SCULPT_floodfill_execute( - struct SculptSession *ss, - SculptFloodFill *flood, - bool (*func)(SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata), - void *userdata); +void SCULPT_floodfill_add_initial(SculptFloodFill *flood, PBVHVertRef vertex); +void SCULPT_floodfill_add_and_skip_initial(SculptFloodFill *flood, PBVHVertRef vertex); +void SCULPT_floodfill_execute(struct SculptSession *ss, + SculptFloodFill *flood, + bool (*func)(SculptSession *ss, + PBVHVertRef from_v, + PBVHVertRef to_v, + bool is_duplicate, + void *userdata), + void *userdata); void SCULPT_floodfill_free(SculptFloodFill *flood); /** \} */ @@ -1276,7 +1286,7 @@ enum eDynTopoWarnFlag SCULPT_dynamic_topology_check(Scene *scene, Object *ob); float SCULPT_automasking_factor_get(struct AutomaskingCache *automasking, SculptSession *ss, - int vert); + PBVHVertRef vertex); /* Returns the automasking cache depending on the active tool. Used for code that can run both for * brushes and filter. */ @@ -1309,9 +1319,9 @@ float *SCULPT_geodesic_distances_create(struct Object *ob, float limit_radius); float *SCULPT_geodesic_from_vertex_and_symm(struct Sculpt *sd, struct Object *ob, - int vertex, + PBVHVertRef vertex, float limit_radius); -float *SCULPT_geodesic_from_vertex(Object *ob, int vertex, float limit_radius); +float *SCULPT_geodesic_from_vertex(Object *ob, PBVHVertRef vertex, float limit_radius); /** \} */ /* -------------------------------------------------------------------- */ @@ -1417,14 +1427,16 @@ BLI_INLINE bool SCULPT_is_cloth_deform_brush(const Brush *brush) */ void SCULPT_bmesh_four_neighbor_average(float avg[3], float direction[3], struct BMVert *v); -void SCULPT_neighbor_coords_average(SculptSession *ss, float result[3], int index); -float SCULPT_neighbor_mask_average(SculptSession *ss, int index); -void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index); +void SCULPT_neighbor_coords_average(SculptSession *ss, float result[3], PBVHVertRef vertex); +float SCULPT_neighbor_mask_average(SculptSession *ss, PBVHVertRef vertex); +void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], PBVHVertRef vertex); /** * Mask the mesh boundaries smoothing only the mesh surface without using auto-masking. */ -void SCULPT_neighbor_coords_average_interior(SculptSession *ss, float result[3], int index); +void SCULPT_neighbor_coords_average_interior(SculptSession *ss, + float result[3], + PBVHVertRef vertex); void SCULPT_smooth( Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float bstrength, bool smooth_mask); @@ -1436,11 +1448,15 @@ void SCULPT_surface_smooth_laplacian_step(SculptSession *ss, float *disp, const float co[3], float (*laplacian_disp)[3], - int v_index, + PBVHVertRef vertex, const float origco[3], float alpha); -void SCULPT_surface_smooth_displace_step( - SculptSession *ss, float *co, float (*laplacian_disp)[3], int v_index, float beta, float fade); +void SCULPT_surface_smooth_displace_step(SculptSession *ss, + float *co, + float (*laplacian_disp)[3], + PBVHVertRef vertex, + float beta, + float fade); void SCULPT_do_surface_smooth_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode); /* Slide/Relax */ @@ -1646,7 +1662,7 @@ void SCULPT_pose_ik_chain_free(struct SculptPoseIKChain *ik_chain); */ struct SculptBoundary *SCULPT_boundary_data_init(Object *object, Brush *brush, - int initial_vertex, + PBVHVertRef initial_vertex, float radius); void SCULPT_boundary_data_free(struct SculptBoundary *boundary); /* Main Brush Function. */ diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c index 03243f00c49..2e661711172 100644 --- a/source/blender/editors/sculpt_paint/sculpt_mask_expand.c +++ b/source/blender/editors/sculpt_paint/sculpt_mask_expand.c @@ -97,11 +97,14 @@ static void sculpt_expand_task_cb(void *__restrict userdata, PBVHVertexIter vd; int update_it = data->mask_expand_update_it; + PBVHVertRef active_vertex = SCULPT_active_vertex_get(ss); + int active_vertex_i = BKE_pbvh_vertex_to_index(ss->pbvh, active_vertex); + BKE_pbvh_vertex_iter_begin (ss->pbvh, node, vd, PBVH_ITER_ALL) { int vi = vd.index; float final_mask = *vd.mask; if (data->mask_expand_use_normals) { - if (ss->filter_cache->normal_factor[SCULPT_active_vertex_get(ss)] < + if (ss->filter_cache->normal_factor[active_vertex_i] < ss->filter_cache->normal_factor[vd.index]) { final_mask = 1.0f; } @@ -121,7 +124,7 @@ static void sculpt_expand_task_cb(void *__restrict userdata, if (data->mask_expand_create_face_set) { if (final_mask == 1.0f) { - SCULPT_vertex_face_set_set(ss, vd.index, ss->filter_cache->new_face_set); + SCULPT_vertex_face_set_set(ss, vd.vertex, ss->filter_cache->new_face_set); } BKE_pbvh_node_mark_redraw(node); } @@ -164,10 +167,13 @@ static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent * if (RNA_boolean_get(op->ptr, "use_cursor")) { SculptCursorGeometryInfo sgi; + const float mval_fl[2] = {UNPACK2(event->mval)}; if (SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false)) { + int active_vertex_i = BKE_pbvh_vertex_to_index(ss->pbvh, SCULPT_active_vertex_get(ss)); + /* The cursor is over the mesh, get the update iteration from the updated active vertex. */ - mask_expand_update_it = ss->filter_cache->mask_update_it[(int)SCULPT_active_vertex_get(ss)]; + mask_expand_update_it = ss->filter_cache->mask_update_it[active_vertex_i]; } else { /* When the cursor is outside the mesh, affect the entire connected component. */ @@ -288,13 +294,16 @@ typedef struct MaskExpandFloodFillData { } MaskExpandFloodFillData; static bool mask_expand_floodfill_cb( - SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata) + SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata) { MaskExpandFloodFillData *data = userdata; + int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); + int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); + if (!is_duplicate) { - int to_it = ss->filter_cache->mask_update_it[from_v] + 1; - ss->filter_cache->mask_update_it[to_v] = to_it; + int to_it = ss->filter_cache->mask_update_it[from_v_i] + 1; + ss->filter_cache->mask_update_it[to_v_i] = to_it; if (to_it > ss->filter_cache->mask_update_last_it) { ss->filter_cache->mask_update_last_it = to_it; } @@ -303,20 +312,20 @@ static bool mask_expand_floodfill_cb( float current_normal[3], prev_normal[3]; SCULPT_vertex_normal_get(ss, to_v, current_normal); SCULPT_vertex_normal_get(ss, from_v, prev_normal); - const float from_edge_factor = ss->filter_cache->edge_factor[from_v]; - ss->filter_cache->edge_factor[to_v] = dot_v3v3(current_normal, prev_normal) * - from_edge_factor; - ss->filter_cache->normal_factor[to_v] = dot_v3v3(data->original_normal, current_normal) * - powf(from_edge_factor, data->edge_sensitivity); - CLAMP(ss->filter_cache->normal_factor[to_v], 0.0f, 1.0f); + const float from_edge_factor = ss->filter_cache->edge_factor[from_v_i]; + ss->filter_cache->edge_factor[to_v_i] = dot_v3v3(current_normal, prev_normal) * + from_edge_factor; + ss->filter_cache->normal_factor[to_v_i] = dot_v3v3(data->original_normal, current_normal) * + powf(from_edge_factor, data->edge_sensitivity); + CLAMP(ss->filter_cache->normal_factor[to_v_i], 0.0f, 1.0f); } } else { /* PBVH_GRIDS duplicate handling. */ - ss->filter_cache->mask_update_it[to_v] = ss->filter_cache->mask_update_it[from_v]; + ss->filter_cache->mask_update_it[to_v_i] = ss->filter_cache->mask_update_it[from_v_i]; if (data->use_normals) { - ss->filter_cache->edge_factor[to_v] = ss->filter_cache->edge_factor[from_v]; - ss->filter_cache->normal_factor[to_v] = ss->filter_cache->normal_factor[from_v]; + ss->filter_cache->edge_factor[to_v_i] = ss->filter_cache->edge_factor[from_v_i]; + ss->filter_cache->normal_factor[to_v_i] = ss->filter_cache->normal_factor[from_v_i]; } } @@ -389,13 +398,17 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent else { ss->filter_cache->prev_mask = MEM_callocN(sizeof(float) * vertex_count, "prev mask"); for (int i = 0; i < vertex_count; i++) { - ss->filter_cache->prev_mask[i] = SCULPT_vertex_mask_get(ss, i); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + ss->filter_cache->prev_mask[i] = SCULPT_vertex_mask_get(ss, vertex); } } + int active_vertex_i = BKE_pbvh_vertex_to_index(ss->pbvh, SCULPT_active_vertex_get(ss)); + ss->filter_cache->mask_update_last_it = 1; ss->filter_cache->mask_update_current_it = 1; - ss->filter_cache->mask_update_it[SCULPT_active_vertex_get(ss)] = 0; + ss->filter_cache->mask_update_it[active_vertex_i] = 0; copy_v3_v3(ss->filter_cache->mask_expand_initial_co, SCULPT_active_vertex_co_get(ss)); @@ -414,9 +427,11 @@ static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent if (use_normals) { for (int repeat = 0; repeat < 2; repeat++) { for (int i = 0; i < vertex_count; i++) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + float avg = 0.0f; SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { avg += ss->filter_cache->normal_factor[ni.index]; } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); diff --git a/source/blender/editors/sculpt_paint/sculpt_mask_init.c b/source/blender/editors/sculpt_paint/sculpt_mask_init.c index 025f34ab2d7..cc27623adb0 100644 --- a/source/blender/editors/sculpt_paint/sculpt_mask_init.c +++ b/source/blender/editors/sculpt_paint/sculpt_mask_init.c @@ -99,7 +99,7 @@ static void mask_init_task_cb(void *__restrict userdata, *vd.mask = BLI_hash_int_01(vd.index + seed); break; case SCULPT_MASK_INIT_RANDOM_PER_FACE_SET: { - const int face_set = SCULPT_vertex_face_set_get(ss, vd.index); + const int face_set = SCULPT_vertex_face_set_get(ss, vd.vertex); *vd.mask = BLI_hash_int_01(face_set + seed); break; } diff --git a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c index 50cb75e8089..1e8731e54c0 100644 --- a/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c +++ b/source/blender/editors/sculpt_paint/sculpt_multiplane_scrape.c @@ -86,7 +86,7 @@ static void calc_multiplane_scrape_surface_task_cb(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); /* Sample the normal and area of the +X and -X axis individually. */ @@ -194,13 +194,13 @@ static void do_multiplane_scrape_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); mul_v3_v3fl(proxy[vd.i], val, fade); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.c b/source/blender/editors/sculpt_paint/sculpt_ops.c index 8f96f5cddea..151eb7744ea 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.c +++ b/source/blender/editors/sculpt_paint/sculpt_ops.c @@ -129,8 +129,10 @@ static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op)) "layer persistent base"); for (int i = 0; i < totvert; i++) { - copy_v3_v3(ss->persistent_base[i].co, SCULPT_vertex_co_get(ss, i)); - SCULPT_vertex_normal_get(ss, i, ss->persistent_base[i].no); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + copy_v3_v3(ss->persistent_base[i].co, SCULPT_vertex_co_get(ss, vertex)); + SCULPT_vertex_normal_get(ss, vertex, ss->persistent_base[i].no); ss->persistent_base[i].disp = 0.0f; } @@ -543,7 +545,7 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); Object *ob = CTX_data_active_object(C); - ss->preview_vert_index_count = 0; + ss->preview_vert_count = 0; int totpoints = 0; /* This function is called from the cursor drawing code, so the PBVH may not be build yet. */ @@ -573,29 +575,32 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float /* Assuming an average of 6 edges per vertex in a triangulated mesh. */ const int max_preview_vertices = SCULPT_vertex_count_get(ss) * 3 * 2; - if (ss->preview_vert_index_list == NULL) { - ss->preview_vert_index_list = MEM_callocN(max_preview_vertices * sizeof(int), "preview lines"); + if (ss->preview_vert_list == NULL) { + ss->preview_vert_list = MEM_callocN(max_preview_vertices * sizeof(PBVHVertRef), + "preview lines"); } - GSQueue *not_visited_vertices = BLI_gsqueue_new(sizeof(int)); - int active_v = SCULPT_active_vertex_get(ss); + GSQueue *not_visited_vertices = BLI_gsqueue_new(sizeof(PBVHVertRef)); + PBVHVertRef active_v = SCULPT_active_vertex_get(ss); BLI_gsqueue_push(not_visited_vertices, &active_v); while (!BLI_gsqueue_is_empty(not_visited_vertices)) { - int from_v; + PBVHVertRef from_v; + BLI_gsqueue_pop(not_visited_vertices, &from_v); SculptVertexNeighborIter ni; SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, from_v, ni) { if (totpoints + (ni.size * 2) < max_preview_vertices) { - int to_v = ni.index; - ss->preview_vert_index_list[totpoints] = from_v; + PBVHVertRef to_v = ni.vertex; + int to_v_i = ni.index; + ss->preview_vert_list[totpoints] = from_v; totpoints++; - ss->preview_vert_index_list[totpoints] = to_v; + ss->preview_vert_list[totpoints] = to_v; totpoints++; - if (BLI_BITMAP_TEST(visited_vertices, to_v)) { + if (BLI_BITMAP_TEST(visited_vertices, to_v_i)) { continue; } - BLI_BITMAP_ENABLE(visited_vertices, to_v); + BLI_BITMAP_ENABLE(visited_vertices, to_v_i); const float *co = SCULPT_vertex_co_for_grab_active_get(ss, to_v); if (len_squared_v3v3(brush_co, co) < radius * radius) { BLI_gsqueue_push(not_visited_vertices, &to_v); @@ -609,152 +614,7 @@ void SCULPT_geometry_preview_lines_update(bContext *C, SculptSession *ss, float MEM_freeN(visited_vertices); - ss->preview_vert_index_count = totpoints; -} - -static int vertex_to_loop_colors_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *ob = CTX_data_active_object(C); - - ID *data; - data = ob->data; - if (data == NULL || ID_IS_LINKED(data) || ID_IS_OVERRIDE_LIBRARY(data)) { - return OPERATOR_CANCELLED; - } - - if (ob->type != OB_MESH) { - return OPERATOR_CANCELLED; - } - - Mesh *mesh = ob->data; - - const int mloopcol_layer_n = CustomData_get_active_layer(&mesh->ldata, CD_PROP_BYTE_COLOR); - if (mloopcol_layer_n == -1) { - return OPERATOR_CANCELLED; - } - MLoopCol *loopcols = CustomData_get_layer_n(&mesh->ldata, CD_PROP_BYTE_COLOR, mloopcol_layer_n); - - const int MPropCol_layer_n = CustomData_get_active_layer(&mesh->vdata, CD_PROP_COLOR); - if (MPropCol_layer_n == -1) { - return OPERATOR_CANCELLED; - } - const MPropCol *vertcols = CustomData_get_layer_n(&mesh->vdata, CD_PROP_COLOR, MPropCol_layer_n); - - const MLoop *loops = CustomData_get_layer(&mesh->ldata, CD_MLOOP); - const MPoly *polys = CustomData_get_layer(&mesh->pdata, CD_MPOLY); - - for (int i = 0; i < mesh->totpoly; i++) { - const MPoly *c_poly = &polys[i]; - for (int j = 0; j < c_poly->totloop; j++) { - int loop_index = c_poly->loopstart + j; - const MLoop *c_loop = &loops[c_poly->loopstart + j]; - float srgb_color[4]; - linearrgb_to_srgb_v4(srgb_color, vertcols[c_loop->v].color); - loopcols[loop_index].r = (char)(srgb_color[0] * 255); - loopcols[loop_index].g = (char)(srgb_color[1] * 255); - loopcols[loop_index].b = (char)(srgb_color[2] * 255); - loopcols[loop_index].a = (char)(srgb_color[3] * 255); - } - } - - DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); - - return OPERATOR_FINISHED; -} - -static bool sculpt_colors_poll(bContext *C) -{ - if (!SCULPT_mode_poll(C)) { - return false; - } - - Object *ob = CTX_data_active_object(C); - - if (!ob->sculpt || !ob->sculpt->pbvh || BKE_pbvh_type(ob->sculpt->pbvh) != PBVH_FACES) { - return false; - } - - return SCULPT_has_colors(ob->sculpt); -} - -static void SCULPT_OT_vertex_to_loop_colors(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Sculpt Vertex Color to Vertex Color"; - ot->description = "Copy the Sculpt Vertex Color to a regular color layer"; - ot->idname = "SCULPT_OT_vertex_to_loop_colors"; - - /* api callbacks */ - ot->poll = sculpt_colors_poll; - ot->exec = vertex_to_loop_colors_exec; - - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -static int loop_to_vertex_colors_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *ob = CTX_data_active_object(C); - - ID *data; - data = ob->data; - if (data == NULL || ID_IS_LINKED(data) || ID_IS_OVERRIDE_LIBRARY(data)) { - return OPERATOR_CANCELLED; - } - - if (ob->type != OB_MESH) { - return OPERATOR_CANCELLED; - } - - Mesh *mesh = ob->data; - - const int mloopcol_layer_n = CustomData_get_active_layer(&mesh->ldata, CD_PROP_BYTE_COLOR); - if (mloopcol_layer_n == -1) { - return OPERATOR_CANCELLED; - } - const MLoopCol *loopcols = CustomData_get_layer_n( - &mesh->ldata, CD_PROP_BYTE_COLOR, mloopcol_layer_n); - - const int MPropCol_layer_n = CustomData_get_active_layer(&mesh->vdata, CD_PROP_COLOR); - if (MPropCol_layer_n == -1) { - return OPERATOR_CANCELLED; - } - MPropCol *vertcols = CustomData_get_layer_n(&mesh->vdata, CD_PROP_COLOR, MPropCol_layer_n); - - const MLoop *loops = CustomData_get_layer(&mesh->ldata, CD_MLOOP); - const MPoly *polys = CustomData_get_layer(&mesh->pdata, CD_MPOLY); - - for (int i = 0; i < mesh->totpoly; i++) { - const MPoly *c_poly = &polys[i]; - for (int j = 0; j < c_poly->totloop; j++) { - int loop_index = c_poly->loopstart + j; - const MLoop *c_loop = &loops[c_poly->loopstart + j]; - vertcols[c_loop->v].color[0] = (loopcols[loop_index].r / 255.0f); - vertcols[c_loop->v].color[1] = (loopcols[loop_index].g / 255.0f); - vertcols[c_loop->v].color[2] = (loopcols[loop_index].b / 255.0f); - vertcols[c_loop->v].color[3] = (loopcols[loop_index].a / 255.0f); - srgb_to_linearrgb_v4(vertcols[c_loop->v].color, vertcols[c_loop->v].color); - } - } - - DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); - - return OPERATOR_FINISHED; -} - -static void SCULPT_OT_loop_to_vertex_colors(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Vertex Color to Sculpt Vertex Color"; - ot->description = "Copy the active loop color layer to the vertex color"; - ot->idname = "SCULPT_OT_loop_to_vertex_colors"; - - /* api callbacks */ - ot->poll = sculpt_colors_poll; - ot->exec = loop_to_vertex_colors_exec; - - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + ss->preview_vert_count = totpoints; } static int sculpt_sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(e)) @@ -764,7 +624,7 @@ static int sculpt_sample_color_invoke(bContext *C, wmOperator *op, const wmEvent Object *ob = CTX_data_active_object(C); Brush *brush = BKE_paint_brush(&sd->paint); SculptSession *ss = ob->sculpt; - int active_vertex = SCULPT_active_vertex_get(ss); + PBVHVertRef active_vertex = SCULPT_active_vertex_get(ss); float active_vertex_color[4]; if (!SCULPT_handles_colors_report(ss, op->reports)) { @@ -890,8 +750,11 @@ static void do_mask_by_color_contiguous_update_nodes_cb( } static bool sculpt_mask_by_color_contiguous_floodfill_cb( - SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata) + SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata) { + int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); + int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); + MaskByColorContiguousFloodFillData *data = userdata; float current_color[4]; @@ -899,10 +762,10 @@ static bool sculpt_mask_by_color_contiguous_floodfill_cb( float new_vertex_mask = sculpt_mask_by_color_delta_get( current_color, data->initial_color, data->threshold, data->invert); - data->new_mask[to_v] = new_vertex_mask; + data->new_mask[to_v_i] = new_vertex_mask; if (is_duplicate) { - data->new_mask[to_v] = data->new_mask[from_v]; + data->new_mask[to_v_i] = data->new_mask[from_v_i]; } float len = len_v3v3(current_color, data->initial_color); @@ -911,7 +774,7 @@ static bool sculpt_mask_by_color_contiguous_floodfill_cb( } static void sculpt_mask_by_color_contiguous(Object *object, - const int vertex, + const PBVHVertRef vertex, const float threshold, const bool invert, const bool preserve_mask) @@ -988,7 +851,7 @@ static void do_mask_by_color_task_cb(void *__restrict userdata, PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { float col[4]; - SCULPT_vertex_color_get(ss, vd.index, col); + SCULPT_vertex_color_get(ss, vd.vertex, col); const float current_mask = *vd.mask; const float new_mask = sculpt_mask_by_color_delta_get(active_color, col, threshold, invert); @@ -1006,7 +869,7 @@ static void do_mask_by_color_task_cb(void *__restrict userdata, } static void sculpt_mask_by_color_full_mesh(Object *object, - const int vertex, + const PBVHVertRef vertex, const float threshold, const bool invert, const bool preserve_mask) @@ -1061,7 +924,7 @@ static int sculpt_mask_by_color_invoke(bContext *C, wmOperator *op, const wmEven SCULPT_undo_push_begin(ob, "Mask by color"); BKE_sculpt_color_layer_create_if_needed(ob); - const int active_vertex = SCULPT_active_vertex_get(ss); + const PBVHVertRef active_vertex = SCULPT_active_vertex_get(ss); const float threshold = RNA_float_get(op->ptr, "threshold"); const bool invert = RNA_boolean_get(op->ptr, "invert"); const bool preserve_mask = RNA_boolean_get(op->ptr, "preserve_previous_mask"); @@ -1150,8 +1013,6 @@ void ED_operatortypes_sculpt(void) WM_operatortype_append(SCULPT_OT_project_line_gesture); WM_operatortype_append(SCULPT_OT_sample_color); - WM_operatortype_append(SCULPT_OT_loop_to_vertex_colors); - WM_operatortype_append(SCULPT_OT_vertex_to_loop_colors); WM_operatortype_append(SCULPT_OT_color_filter); WM_operatortype_append(SCULPT_OT_mask_by_color); WM_operatortype_append(SCULPT_OT_dyntopo_detail_size_edit); diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_color.c b/source/blender/editors/sculpt_paint/sculpt_paint_color.c index 3b65124fe02..c494c71f1eb 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_color.c +++ b/source/blender/editors/sculpt_paint/sculpt_paint_color.c @@ -81,16 +81,16 @@ static void do_color_smooth_task_cb_exec(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); float smooth_color[4]; - SCULPT_neighbor_color_average(ss, smooth_color, vd.index); + SCULPT_neighbor_color_average(ss, smooth_color, vd.vertex); float col[4]; - SCULPT_vertex_color_get(ss, vd.index, col); + SCULPT_vertex_color_get(ss, vd.vertex, col); blend_color_interpolate_float(col, col, smooth_color, fade); - SCULPT_vertex_color_set(ss, vd.index, col); + SCULPT_vertex_color_set(ss, vd.vertex, col); } BKE_pbvh_vertex_iter_end; } @@ -168,7 +168,7 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); /* Density. */ @@ -199,10 +199,10 @@ static void do_paint_brush_task_cb_ex(void *__restrict userdata, mul_v4_v4fl(buffer_color, color_buffer->color[vd.i], brush->alpha); float col[4]; - SCULPT_vertex_color_get(ss, vd.index, col); + SCULPT_vertex_color_get(ss, vd.vertex, col); IMB_blend_color_float(col, orig_data.col, buffer_color, brush->blend); CLAMP4(col, 0.0f, 1.0f); - SCULPT_vertex_color_set(ss, vd.index, col); + SCULPT_vertex_color_set(ss, vd.vertex, col); } BKE_pbvh_vertex_iter_end; } @@ -234,7 +234,7 @@ static void do_sample_wet_paint_task_cb(void *__restrict userdata, } float col[4]; - SCULPT_vertex_color_get(ss, vd.index, col); + SCULPT_vertex_color_get(ss, vd.vertex, col); add_v4_v4(swptd->color, col); swptd->tot_samples++; @@ -413,7 +413,7 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); float current_disp[3]; @@ -422,7 +422,7 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata, copy_v4_v4(interp_color, ss->cache->prev_colors[vd.index]); float no[3]; - SCULPT_vertex_normal_get(ss, vd.index, no); + SCULPT_vertex_normal_get(ss, vd.vertex, no); switch (brush->smear_deform_type) { case BRUSH_SMEAR_DEFORM_DRAG: @@ -455,11 +455,11 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata, */ SculptVertexNeighborIter ni2; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni2) { - const float *nco = SCULPT_vertex_co_get(ss, ni2.index); + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni2) { + const float *nco = SCULPT_vertex_co_get(ss, ni2.vertex); SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, ni2.index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, ni2.vertex, ni) { if (ni.index == vd.index) { continue; } @@ -467,13 +467,13 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata, float vertex_disp[3]; float vertex_disp_norm[3]; - sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.index), vd.co); + sub_v3_v3v3(vertex_disp, SCULPT_vertex_co_get(ss, ni.vertex), vd.co); /* Weight by how close we are to our target distance from vd.co. */ float w = (1.0f + fabsf(len_v3(vertex_disp) / bstrength - 1.0f)); /* TODO: use cotangents (or at least face areas) here. */ - float len = len_v3v3(SCULPT_vertex_co_get(ss, ni.index), nco); + float len = len_v3v3(SCULPT_vertex_co_get(ss, ni.vertex), nco); if (len > 0.0f) { len = bstrength / len; } @@ -515,9 +515,9 @@ static void do_smear_brush_task_cb_exec(void *__restrict userdata, blend_color_mix_float(interp_color, interp_color, accum); float col[4]; - SCULPT_vertex_color_get(ss, vd.index, col); + SCULPT_vertex_color_get(ss, vd.vertex, col); blend_color_interpolate_float(col, ss->cache->prev_colors[vd.index], interp_color, fade); - SCULPT_vertex_color_set(ss, vd.index, col); + SCULPT_vertex_color_set(ss, vd.vertex, col); } BKE_pbvh_vertex_iter_end; } @@ -531,7 +531,7 @@ static void do_smear_store_prev_colors_task_cb_exec(void *__restrict userdata, PBVHVertexIter vd; BKE_pbvh_vertex_iter_begin (ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { - SCULPT_vertex_color_get(ss, vd.index, ss->cache->prev_colors[vd.index]); + SCULPT_vertex_color_get(ss, vd.vertex, ss->cache->prev_colors[vd.index]); } BKE_pbvh_vertex_iter_end; } @@ -550,7 +550,9 @@ void SCULPT_do_smear_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode if (!ss->cache->prev_colors) { ss->cache->prev_colors = MEM_callocN(sizeof(float[4]) * totvert, "prev colors"); for (int i = 0; i < totvert; i++) { - SCULPT_vertex_color_get(ss, i, ss->cache->prev_colors[i]); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + SCULPT_vertex_color_get(ss, vertex, ss->cache->prev_colors[i]); } } diff --git a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc index f51a603ee5d..8a3a3fe7adc 100644 --- a/source/blender/editors/sculpt_paint/sculpt_paint_image.cc +++ b/source/blender/editors/sculpt_paint/sculpt_paint_image.cc @@ -172,7 +172,15 @@ template<typename ImageBuffer> class PaintingKernel { const float3 face_normal(0.0f, 0.0f, 0.0f); const float mask = 0.0f; const float falloff_strength = SCULPT_brush_strength_factor( - ss, brush, pixel_pos, sqrtf(test.dist), normal, face_normal, mask, 0, thread_id); + ss, + brush, + pixel_pos, + sqrtf(test.dist), + normal, + face_normal, + mask, + BKE_pbvh_make_vref(PBVH_REF_NONE), + thread_id); float4 paint_color = brush_color * falloff_strength * brush_strength; float4 buffer_color; blend_color_mix_float(buffer_color, color, paint_color); diff --git a/source/blender/editors/sculpt_paint/sculpt_pose.c b/source/blender/editors/sculpt_paint/sculpt_pose.c index 6f600489729..d1418c8dc35 100644 --- a/source/blender/editors/sculpt_paint/sculpt_pose.c +++ b/source/blender/editors/sculpt_paint/sculpt_pose.c @@ -182,7 +182,7 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata, /* Apply the vertex mask to the displacement. */ const float mask = vd.mask ? 1.0f - *vd.mask : 1.0f; - const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.index); + const float automask = SCULPT_automasking_factor_get(ss->cache->automasking, ss, vd.vertex); mul_v3_fl(disp, mask * automask); /* Accumulate the displacement. */ @@ -196,7 +196,7 @@ static void do_pose_brush_task_cb_ex(void *__restrict userdata, copy_v3_v3(target_co, final_pos); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -221,7 +221,7 @@ static void pose_brush_grow_factor_task_cb_ex(void *__restrict userdata, float max = 0.0f; /* Grow the factor. */ - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) { float vmask_f = data->prev_mask[ni.index]; max = MAX2(vmask_f, max); } @@ -367,7 +367,7 @@ typedef struct PoseFloodFillData { int current_face_set; int next_face_set; int prev_face_set; - int next_vertex; + PBVHVertRef next_vertex; bool next_face_set_found; @@ -397,14 +397,19 @@ typedef struct PoseFloodFillData { int target_face_set; } PoseFloodFillData; -static bool pose_topology_floodfill_cb( - SculptSession *ss, int UNUSED(from_v), int to_v, bool is_duplicate, void *userdata) +static bool pose_topology_floodfill_cb(SculptSession *ss, + PBVHVertRef UNUSED(from_v), + PBVHVertRef to_v, + bool is_duplicate, + void *userdata) { + int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); + PoseFloodFillData *data = userdata; const float *co = SCULPT_vertex_co_get(ss, to_v); if (data->pose_factor) { - data->pose_factor[to_v] = 1.0f; + data->pose_factor[to_v_i] = 1.0f; } if (len_squared_v3v3(data->pose_initial_co, data->fallback_floodfill_origin) < @@ -426,15 +431,19 @@ static bool pose_topology_floodfill_cb( return false; } -static bool pose_face_sets_floodfill_cb( - SculptSession *ss, int UNUSED(from_v), int to_v, bool is_duplicate, void *userdata) +static bool pose_face_sets_floodfill_cb(SculptSession *ss, + PBVHVertRef UNUSED(from_v), + PBVHVertRef to_v, + bool is_duplicate, + void *userdata) { PoseFloodFillData *data = userdata; - const int index = to_v; + const int index = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); + const PBVHVertRef vertex = to_v; bool visit_next = false; - const float *co = SCULPT_vertex_co_get(ss, index); + const float *co = SCULPT_vertex_co_get(ss, vertex); const bool symmetry_check = SCULPT_check_vertex_pivot_symmetry( co, data->pose_initial_co, data->symm) && !is_duplicate; @@ -448,11 +457,11 @@ static bool pose_face_sets_floodfill_cb( if (sculpt_pose_brush_is_vertex_inside_brush_radius( co, data->pose_initial_co, data->radius, data->symm)) { - const int visited_face_set = SCULPT_vertex_face_set_get(ss, index); + const int visited_face_set = SCULPT_vertex_face_set_get(ss, vertex); BLI_gset_add(data->visited_face_sets, POINTER_FROM_INT(visited_face_set)); } else if (symmetry_check) { - data->current_face_set = SCULPT_vertex_face_set_get(ss, index); + data->current_face_set = SCULPT_vertex_face_set_get(ss, vertex); BLI_gset_add(data->visited_face_sets, POINTER_FROM_INT(data->current_face_set)); } return true; @@ -466,11 +475,11 @@ static bool pose_face_sets_floodfill_cb( GSetIterator gs_iter; GSET_ITER (gs_iter, data->visited_face_sets) { const int visited_face_set = POINTER_AS_INT(BLI_gsetIterator_getKey(&gs_iter)); - is_vertex_valid |= SCULPT_vertex_has_face_set(ss, index, visited_face_set); + is_vertex_valid |= SCULPT_vertex_has_face_set(ss, vertex, visited_face_set); } } else { - is_vertex_valid = SCULPT_vertex_has_face_set(ss, index, data->current_face_set); + is_vertex_valid = SCULPT_vertex_has_face_set(ss, vertex, data->current_face_set); } if (!is_vertex_valid) { @@ -485,11 +494,11 @@ static bool pose_face_sets_floodfill_cb( /* Fallback origin accumulation. */ if (symmetry_check) { - add_v3_v3(data->fallback_origin, SCULPT_vertex_co_get(ss, index)); + add_v3_v3(data->fallback_origin, SCULPT_vertex_co_get(ss, vertex)); data->fallback_count++; } - if (!symmetry_check || SCULPT_vertex_has_unique_face_set(ss, index)) { + if (!symmetry_check || SCULPT_vertex_has_unique_face_set(ss, vertex)) { return visit_next; } @@ -498,15 +507,15 @@ static bool pose_face_sets_floodfill_cb( bool count_as_boundary = false; SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) { - int next_face_set_candidate = SCULPT_vertex_face_set_get(ss, ni.index); + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { + int next_face_set_candidate = SCULPT_vertex_face_set_get(ss, ni.vertex); /* Check if we can get a valid face set for the next iteration from this neighbor. */ - if (SCULPT_vertex_has_unique_face_set(ss, ni.index) && + if (SCULPT_vertex_has_unique_face_set(ss, ni.vertex) && !BLI_gset_haskey(data->visited_face_sets, POINTER_FROM_INT(next_face_set_candidate))) { if (!data->next_face_set_found) { data->next_face_set = next_face_set_candidate; - data->next_vertex = ni.index; + data->next_vertex = ni.vertex; data->next_face_set_found = true; } count_as_boundary = true; @@ -516,7 +525,7 @@ static bool pose_face_sets_floodfill_cb( /* Origin accumulation. */ if (count_as_boundary) { - add_v3_v3(data->pose_origin, SCULPT_vertex_co_get(ss, index)); + add_v3_v3(data->pose_origin, SCULPT_vertex_co_get(ss, vertex)); data->tot_co++; } return visit_next; @@ -585,7 +594,7 @@ static void pose_brush_init_task_cb_ex(void *__restrict userdata, SculptVertexNeighborIter ni; float avg = 0.0f; int total = 0; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) { avg += data->pose_factor[ni.index]; total++; } @@ -660,7 +669,8 @@ static SculptPoseIKChain *pose_ik_chain_init_topology(Sculpt *sd, float next_chain_segment_target[3]; int totvert = SCULPT_vertex_count_get(ss); - int nearest_vertex_index = SCULPT_nearest_vertex_get(sd, ob, initial_location, FLT_MAX, true); + PBVHVertRef nearest_vertex = SCULPT_nearest_vertex_get(sd, ob, initial_location, FLT_MAX, true); + int nearest_vertex_index = BKE_pbvh_vertex_to_index(ss->pbvh, nearest_vertex); /* Init the buffers used to keep track of the changes in the pose factors as more segments are * added to the IK chain. */ @@ -745,7 +755,7 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets( int current_face_set = SCULPT_FACE_SET_NONE; int prev_face_set = SCULPT_FACE_SET_NONE; - int current_vertex = SCULPT_active_vertex_get(ss); + PBVHVertRef current_vertex = SCULPT_active_vertex_get(ss); for (int s = 0; s < ik_chain->tot_segments; s++) { @@ -801,15 +811,18 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets( } static bool pose_face_sets_fk_find_masked_floodfill_cb( - SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata) + SculptSession *ss, PBVHVertRef from_v, PBVHVertRef to_v, bool is_duplicate, void *userdata) { PoseFloodFillData *data = userdata; + int from_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, from_v); + int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); + if (!is_duplicate) { - data->floodfill_it[to_v] = data->floodfill_it[from_v] + 1; + data->floodfill_it[to_v_i] = data->floodfill_it[from_v_i] + 1; } else { - data->floodfill_it[to_v] = data->floodfill_it[from_v]; + data->floodfill_it[to_v_i] = data->floodfill_it[from_v_i]; } const int to_face_set = SCULPT_vertex_face_set_get(ss, to_v); @@ -820,9 +833,9 @@ static bool pose_face_sets_fk_find_masked_floodfill_cb( BLI_gset_add(data->visited_face_sets, POINTER_FROM_INT(to_face_set)); - if (data->floodfill_it[to_v] >= data->masked_face_set_it) { + if (data->floodfill_it[to_v_i] >= data->masked_face_set_it) { data->masked_face_set = to_face_set; - data->masked_face_set_it = data->floodfill_it[to_v]; + data->masked_face_set_it = data->floodfill_it[to_v_i]; } if (data->target_face_set == SCULPT_FACE_SET_NONE) { @@ -834,11 +847,17 @@ static bool pose_face_sets_fk_find_masked_floodfill_cb( return SCULPT_vertex_has_face_set(ss, to_v, data->initial_face_set); } -static bool pose_face_sets_fk_set_weights_floodfill_cb( - SculptSession *ss, int UNUSED(from_v), int to_v, bool UNUSED(is_duplicate), void *userdata) +static bool pose_face_sets_fk_set_weights_floodfill_cb(SculptSession *ss, + PBVHVertRef UNUSED(from_v), + PBVHVertRef to_v, + bool UNUSED(is_duplicate), + void *userdata) { PoseFloodFillData *data = userdata; - data->fk_weights[to_v] = 1.0f; + + int to_v_i = BKE_pbvh_vertex_to_index(ss->pbvh, to_v); + + data->fk_weights[to_v_i] = 1.0f; return !SCULPT_vertex_has_face_set(ss, to_v, data->masked_face_set); } @@ -849,7 +868,9 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk( SculptPoseIKChain *ik_chain = pose_ik_chain_new(1, totvert); - const int active_vertex = SCULPT_active_vertex_get(ss); + const PBVHVertRef active_vertex = SCULPT_active_vertex_get(ss); + int active_vertex_index = BKE_pbvh_vertex_to_index(ss->pbvh, active_vertex); + const int active_face_set = SCULPT_active_face_set_get(ss); SculptFloodFill flood; @@ -857,7 +878,7 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk( SCULPT_floodfill_add_initial(&flood, active_vertex); PoseFloodFillData fdata; fdata.floodfill_it = MEM_calloc_arrayN(totvert, sizeof(int), "floodfill iteration"); - fdata.floodfill_it[active_vertex] = 1; + fdata.floodfill_it[active_vertex_index] = 1; fdata.initial_face_set = active_face_set; fdata.masked_face_set = SCULPT_FACE_SET_NONE; fdata.target_face_set = SCULPT_FACE_SET_NONE; @@ -870,9 +891,12 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk( int origin_count = 0; float origin_acc[3] = {0.0f}; for (int i = 0; i < totvert; i++) { - if (fdata.floodfill_it[i] != 0 && SCULPT_vertex_has_face_set(ss, i, fdata.initial_face_set) && - SCULPT_vertex_has_face_set(ss, i, fdata.masked_face_set)) { - add_v3_v3(origin_acc, SCULPT_vertex_co_get(ss, i)); + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + + if (fdata.floodfill_it[i] != 0 && + SCULPT_vertex_has_face_set(ss, vertex, fdata.initial_face_set) && + SCULPT_vertex_has_face_set(ss, vertex, fdata.masked_face_set)) { + add_v3_v3(origin_acc, SCULPT_vertex_co_get(ss, vertex)); origin_count++; } } @@ -881,10 +905,12 @@ static SculptPoseIKChain *pose_ik_chain_init_face_sets_fk( float target_acc[3] = {0.0f}; if (fdata.target_face_set != fdata.masked_face_set) { for (int i = 0; i < totvert; i++) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + if (fdata.floodfill_it[i] != 0 && - SCULPT_vertex_has_face_set(ss, i, fdata.initial_face_set) && - SCULPT_vertex_has_face_set(ss, i, fdata.target_face_set)) { - add_v3_v3(target_acc, SCULPT_vertex_co_get(ss, i)); + SCULPT_vertex_has_face_set(ss, vertex, fdata.initial_face_set) && + SCULPT_vertex_has_face_set(ss, vertex, fdata.target_face_set)) { + add_v3_v3(target_acc, SCULPT_vertex_co_get(ss, vertex)); target_count++; } } diff --git a/source/blender/editors/sculpt_paint/sculpt_smooth.c b/source/blender/editors/sculpt_paint/sculpt_smooth.c index d6b9b500501..2ef3c28ba0c 100644 --- a/source/blender/editors/sculpt_paint/sculpt_smooth.c +++ b/source/blender/editors/sculpt_paint/sculpt_smooth.c @@ -46,26 +46,28 @@ #include <math.h> #include <stdlib.h> -void SCULPT_neighbor_coords_average_interior(SculptSession *ss, float result[3], int index) +void SCULPT_neighbor_coords_average_interior(SculptSession *ss, + float result[3], + PBVHVertRef vertex) { float avg[3] = {0.0f, 0.0f, 0.0f}; int total = 0; int neighbor_count = 0; - const bool is_boundary = SCULPT_vertex_is_boundary(ss, index); + const bool is_boundary = SCULPT_vertex_is_boundary(ss, vertex); SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { neighbor_count++; if (is_boundary) { /* Boundary vertices use only other boundary vertices. */ - if (SCULPT_vertex_is_boundary(ss, ni.index)) { - add_v3_v3(avg, SCULPT_vertex_co_get(ss, ni.index)); + if (SCULPT_vertex_is_boundary(ss, ni.vertex)) { + add_v3_v3(avg, SCULPT_vertex_co_get(ss, ni.vertex)); total++; } } else { /* Interior vertices use all neighbors. */ - add_v3_v3(avg, SCULPT_vertex_co_get(ss, ni.index)); + add_v3_v3(avg, SCULPT_vertex_co_get(ss, ni.vertex)); total++; } } @@ -73,13 +75,13 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss, float result[3], /* Do not modify corner vertices. */ if (neighbor_count <= 2 && is_boundary) { - copy_v3_v3(result, SCULPT_vertex_co_get(ss, index)); + copy_v3_v3(result, SCULPT_vertex_co_get(ss, vertex)); return; } /* Avoid division by 0 when there are no neighbors. */ if (total == 0) { - copy_v3_v3(result, SCULPT_vertex_co_get(ss, index)); + copy_v3_v3(result, SCULPT_vertex_co_get(ss, vertex)); return; } @@ -134,14 +136,14 @@ void SCULPT_bmesh_four_neighbor_average(float avg[3], float direction[3], BMVert /* Generic functions for laplacian smoothing. These functions do not take boundary vertices into * account. */ -void SCULPT_neighbor_coords_average(SculptSession *ss, float result[3], int index) +void SCULPT_neighbor_coords_average(SculptSession *ss, float result[3], PBVHVertRef vertex) { float avg[3] = {0.0f, 0.0f, 0.0f}; int total = 0; SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) { - add_v3_v3(avg, SCULPT_vertex_co_get(ss, ni.index)); + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { + add_v3_v3(avg, SCULPT_vertex_co_get(ss, ni.vertex)); total++; } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); @@ -150,18 +152,18 @@ void SCULPT_neighbor_coords_average(SculptSession *ss, float result[3], int inde mul_v3_v3fl(result, avg, 1.0f / total); } else { - copy_v3_v3(result, SCULPT_vertex_co_get(ss, index)); + copy_v3_v3(result, SCULPT_vertex_co_get(ss, vertex)); } } -float SCULPT_neighbor_mask_average(SculptSession *ss, int index) +float SCULPT_neighbor_mask_average(SculptSession *ss, PBVHVertRef vertex) { float avg = 0.0f; int total = 0; SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) { - avg += SCULPT_vertex_mask_get(ss, ni.index); + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { + avg += SCULPT_vertex_mask_get(ss, ni.vertex); total++; } SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); @@ -169,19 +171,19 @@ float SCULPT_neighbor_mask_average(SculptSession *ss, int index) if (total > 0) { return avg / total; } - return SCULPT_vertex_mask_get(ss, index); + return SCULPT_vertex_mask_get(ss, vertex); } -void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index) +void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], PBVHVertRef vertex) { float avg[4] = {0.0f, 0.0f, 0.0f, 0.0f}; int total = 0; SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { float tmp[4] = {0}; - SCULPT_vertex_color_get(ss, ni.index, tmp); + SCULPT_vertex_color_get(ss, ni.vertex, tmp); add_v4_v4(avg, tmp); total++; @@ -192,7 +194,7 @@ void SCULPT_neighbor_color_average(SculptSession *ss, float result[4], int index mul_v4_v4fl(result, avg, 1.0f / total); } else { - SCULPT_vertex_color_get(ss, index, result); + SCULPT_vertex_color_get(ss, vertex, result); } } @@ -227,7 +229,7 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); float disp[3]; @@ -235,7 +237,7 @@ static void do_enhance_details_brush_task_cb_ex(void *__restrict userdata, SCULPT_clip(sd, ss, vd.co, disp); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -258,9 +260,11 @@ static void SCULPT_enhance_details_brush(Sculpt *sd, totvert, sizeof(float[3]), "details directions"); for (int i = 0; i < totvert; i++) { + PBVHVertRef vertex = BKE_pbvh_index_to_vertex(ss->pbvh, i); + float avg[3]; - SCULPT_neighbor_coords_average(ss, avg, i); - sub_v3_v3v3(ss->cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, i)); + SCULPT_neighbor_coords_average(ss, avg, vertex); + sub_v3_v3v3(ss->cache->detail_directions[i], avg, SCULPT_vertex_co_get(ss, vertex)); } } @@ -309,22 +313,22 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata, vd.no, vd.fno, smooth_mask ? 0.0f : (vd.mask ? *vd.mask : 0.0f), - vd.index, + vd.vertex, thread_id); if (smooth_mask) { - float val = SCULPT_neighbor_mask_average(ss, vd.index) - *vd.mask; + float val = SCULPT_neighbor_mask_average(ss, vd.vertex) - *vd.mask; val *= fade * bstrength; *vd.mask += val; CLAMP(*vd.mask, 0.0f, 1.0f); } else { float avg[3], val[3]; - SCULPT_neighbor_coords_average_interior(ss, avg, vd.index); + SCULPT_neighbor_coords_average_interior(ss, avg, vd.vertex); sub_v3_v3v3(val, avg, vd.co); madd_v3_v3v3fl(val, vd.co, val, fade); SCULPT_clip(sd, ss, vd.co, val); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } } @@ -403,13 +407,15 @@ void SCULPT_surface_smooth_laplacian_step(SculptSession *ss, float *disp, const float co[3], float (*laplacian_disp)[3], - const int v_index, + const PBVHVertRef vertex, const float origco[3], const float alpha) { float laplacian_smooth_co[3]; float weigthed_o[3], weigthed_q[3], d[3]; - SCULPT_neighbor_coords_average(ss, laplacian_smooth_co, v_index); + int v_index = BKE_pbvh_vertex_to_index(ss->pbvh, vertex); + + SCULPT_neighbor_coords_average(ss, laplacian_smooth_co, vertex); mul_v3_v3fl(weigthed_o, origco, alpha); mul_v3_v3fl(weigthed_q, co, 1.0f - alpha); @@ -422,7 +428,7 @@ void SCULPT_surface_smooth_laplacian_step(SculptSession *ss, void SCULPT_surface_smooth_displace_step(SculptSession *ss, float *co, float (*laplacian_disp)[3], - const int v_index, + const PBVHVertRef vertex, const float beta, const float fade) { @@ -430,12 +436,15 @@ void SCULPT_surface_smooth_displace_step(SculptSession *ss, float b_current_vertex[3]; int total = 0; SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, v_index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { add_v3_v3(b_avg, laplacian_disp[ni.index]); total++; } + SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); if (total > 0) { + int v_index = BKE_pbvh_vertex_to_index(ss->pbvh, vertex); + mul_v3_v3fl(b_current_vertex, b_avg, (1.0f - beta) / total); madd_v3_v3fl(b_current_vertex, laplacian_disp[v_index], beta); mul_v3_fl(b_current_vertex, clamp_f(fade, 0.0f, 1.0f)); @@ -474,15 +483,15 @@ static void SCULPT_do_surface_smooth_brush_laplacian_task_cb_ex( vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); float disp[3]; SCULPT_surface_smooth_laplacian_step( - ss, disp, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, orig_data.co, alpha); + ss, disp, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.vertex, orig_data.co, alpha); madd_v3_v3fl(vd.co, disp, clamp_f(fade, 0.0f, 1.0f)); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -515,10 +524,10 @@ static void SCULPT_do_surface_smooth_brush_displace_task_cb_ex( vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, - vd.index, + vd.vertex, thread_id); SCULPT_surface_smooth_displace_step( - ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.index, beta, fade); + ss, vd.co, ss->cache->surface_smooth_laplacian_disp, vd.vertex, beta, fade); } BKE_pbvh_vertex_iter_end; } diff --git a/source/blender/editors/sculpt_paint/sculpt_transform.c b/source/blender/editors/sculpt_paint/sculpt_transform.c index 2a7c6c8d0e0..7207e6c35d4 100644 --- a/source/blender/editors/sculpt_paint/sculpt_transform.c +++ b/source/blender/editors/sculpt_paint/sculpt_transform.c @@ -179,7 +179,7 @@ static void sculpt_transform_task_cb(void *__restrict userdata, add_v3_v3v3(vd.co, start_co, disp); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; @@ -253,7 +253,7 @@ static void sculpt_elastic_transform_task_cb(void *__restrict userdata, copy_v3_v3(proxy[vd.i], final_disp); if (vd.mvert) { - BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.index); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, vd.vertex); } } BKE_pbvh_vertex_iter_end; diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index d37d0d2681f..dc814d6d22f 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -297,20 +297,20 @@ static bool sculpt_undo_restore_coords(bContext *C, Depsgraph *depsgraph, Sculpt if (ss->deform_modifiers_active) { for (int i = 0; i < unode->totvert; i++) { sculpt_undo_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co); - BKE_pbvh_vert_tag_update_normal(ss->pbvh, index[i]); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, BKE_pbvh_make_vref(index[i])); } } else { for (int i = 0; i < unode->totvert; i++) { swap_v3_v3(mvert[index[i]].co, unode->orig_co[i]); - BKE_pbvh_vert_tag_update_normal(ss->pbvh, index[i]); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, BKE_pbvh_make_vref(index[i])); } } } else { for (int i = 0; i < unode->totvert; i++) { swap_v3_v3(mvert[index[i]].co, unode->co[i]); - BKE_pbvh_vert_tag_update_normal(ss->pbvh, index[i]); + BKE_pbvh_vert_tag_update_normal(ss->pbvh, BKE_pbvh_make_vref(index[i])); } } } diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c index dfa85e8e56d..2e2abd30ea2 100644 --- a/source/blender/editors/sculpt_paint/sculpt_uv.c +++ b/source/blender/editors/sculpt_paint/sculpt_uv.c @@ -414,9 +414,8 @@ static void uv_sculpt_stroke_exit(bContext *C, wmOperator *op) if (data->timer) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), data->timer); } - if (data->elementMap) { - BM_uv_element_map_free(data->elementMap); - } + BM_uv_element_map_free(data->elementMap); + data->elementMap = NULL; MEM_SAFE_FREE(data->uv); MEM_SAFE_FREE(data->uvedges); if (data->initial_stroke) { @@ -435,7 +434,7 @@ static int uv_element_offset_from_face_get( if (!element || (doIslands && element->island != island_index)) { return -1; } - return element - map->buf; + return element - map->storage; } static uint uv_edge_hash(const void *key) @@ -469,7 +468,6 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm BKE_curvemapping_init(ts->uvsculpt->paint.brush->curve); if (data) { - int counter = 0, i; ARegion *region = CTX_wm_region(C); float co[2]; BMFace *efa; @@ -492,13 +490,12 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm data->uvsculpt = &ts->uvsculpt->paint; - if (do_island_optimization) { - /* We will need island information */ - data->elementMap = BM_uv_element_map_create(bm, scene, false, true, true); - } - else { - data->elementMap = BM_uv_element_map_create(bm, scene, false, true, false); - } + /* Winding was added to island detection in 5197aa04c6bd + * However the sculpt tools can flip faces, potentially creating orphaned islands. + * See T100132 */ + bool use_winding = false; + data->elementMap = BM_uv_element_map_create( + bm, scene, false, use_winding, do_island_optimization); if (!data->elementMap) { uv_sculpt_stroke_exit(C, op); @@ -519,20 +516,24 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm } /* Count 'unique' UV's */ - for (i = 0; i < data->elementMap->totalUVs; i++) { - if (data->elementMap->buf[i].separate && - (!do_island_optimization || data->elementMap->buf[i].island == island_index)) { - counter++; + int unique_uvs = data->elementMap->total_unique_uvs; + if (do_island_optimization) { + unique_uvs = 0; + for (int i = 0; i < data->elementMap->total_uvs; i++) { + if (data->elementMap->storage[i].separate && + (data->elementMap->storage[i].island == island_index)) { + unique_uvs++; + } } } /* Allocate the unique uv buffers */ - data->uv = MEM_mallocN(sizeof(*data->uv) * counter, "uv_brush_unique_uvs"); - uniqueUv = MEM_mallocN(sizeof(*uniqueUv) * data->elementMap->totalUVs, + data->uv = MEM_mallocN(sizeof(*data->uv) * unique_uvs, "uv_brush_unique_uvs"); + uniqueUv = MEM_mallocN(sizeof(*uniqueUv) * data->elementMap->total_uvs, "uv_brush_unique_uv_map"); edgeHash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "uv_brush_edge_hash"); /* we have at most totalUVs edges */ - edges = MEM_mallocN(sizeof(*edges) * data->elementMap->totalUVs, "uv_brush_all_edges"); + edges = MEM_mallocN(sizeof(*edges) * data->elementMap->total_uvs, "uv_brush_all_edges"); if (!data->uv || !uniqueUv || !edgeHash || !edges) { MEM_SAFE_FREE(edges); MEM_SAFE_FREE(uniqueUv); @@ -543,12 +544,12 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm return NULL; } - data->totalUniqueUvs = counter; - /* So that we can use this as index for the UvElements */ - counter = -1; + data->totalUniqueUvs = unique_uvs; + /* Index for the UvElements. */ + int counter = -1; /* initialize the unique UVs */ - for (i = 0; i < bm->totvert; i++) { - UvElement *element = data->elementMap->vert[i]; + for (int i = 0; i < bm->totvert; i++) { + UvElement *element = data->elementMap->vertex[i]; for (; element; element = element->next) { if (element->separate) { if (do_island_optimization && (element->island != island_index)) { @@ -568,7 +569,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm data->uv[counter].uv = luv->uv; } /* Pointer arithmetic to the rescue, as always :). */ - uniqueUv[element - data->elementMap->buf] = counter; + uniqueUv[element - data->elementMap->storage] = counter; } } @@ -628,11 +629,13 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm } /* fill the edges with data */ - i = 0; - GHASH_ITER (gh_iter, edgeHash) { - data->uvedges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(&gh_iter)); + { + int i = 0; + GHASH_ITER (gh_iter, edgeHash) { + data->uvedges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(&gh_iter)); + } + data->totalUvEdges = BLI_ghash_len(edgeHash); } - data->totalUvEdges = BLI_ghash_len(edgeHash); /* cleanup temporary stuff */ BLI_ghash_free(edgeHash, NULL, NULL); @@ -640,7 +643,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm /* transfer boundary edge property to UV's */ if (ts->uv_sculpt_settings & UV_SCULPT_LOCK_BORDERS) { - for (i = 0; i < data->totalUvEdges; i++) { + for (int i = 0; i < data->totalUvEdges; i++) { if (!data->uvedges[i].flag) { data->uv[data->uvedges[i].uv1].flag |= MARK_BOUNDARY; data->uv[data->uvedges[i].uv2].flag |= MARK_BOUNDARY; @@ -687,7 +690,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm counter = 0; - for (i = 0; i < data->totalUniqueUvs; i++) { + for (int i = 0; i < data->totalUniqueUvs; i++) { float dist, diff[2]; if (data->uv[i].flag & MARK_BOUNDARY) { continue; diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index d1a8592ae9d..ed9d86e1a4e 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -919,7 +919,7 @@ static const EnumPropertyItem prop_column_select_types[] = { /* ------------------- */ /* Selects all visible keyframes between the specified markers */ -/* TODO(campbell): this is almost an _exact_ duplicate of a function of the same name in +/* TODO(@campbellbarton): this is almost an _exact_ duplicate of a function of the same name in * graph_select.c should de-duplicate. */ static void markers_selectkeys_between(bAnimContext *ac) { diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt index 7d4f38b1841..b509eae8ea6 100644 --- a/source/blender/editors/space_buttons/CMakeLists.txt +++ b/source/blender/editors/space_buttons/CMakeLists.txt @@ -11,6 +11,7 @@ set(INC ../../windowmanager ../../../../intern/glew-mx ../../../../intern/guardedalloc + ../../bmesh # RNA_prototypes.h ${CMAKE_BINARY_DIR}/source/blender/makesrna ) diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index a36bd5c1461..0ce3e1a797a 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -1128,7 +1128,7 @@ static const EnumPropertyItem prop_column_select_types[] = { /* ------------------- */ /* Selects all visible keyframes between the specified markers */ -/* TODO(campbell): this is almost an _exact_ duplicate of a function of the same name in +/* TODO(@campbellbarton): this is almost an _exact_ duplicate of a function of the same name in * action_select.c should de-duplicate. */ static void markers_selectkeys_between(bAnimContext *ac) { diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c index 0a774ee679c..2109d3f9701 100644 --- a/source/blender/editors/space_image/image_buttons.c +++ b/source/blender/editors/space_image/image_buttons.c @@ -869,7 +869,8 @@ void uiTemplateImage(uiLayout *layout, uiItemS(col); uiItemR(col, &imaptr, "generated_type", UI_ITEM_R_EXPAND, IFACE_("Type"), ICON_NONE); - if (ima->gen_type == IMA_GENTYPE_BLANK) { + ImageTile *base_tile = BKE_image_get_tile(ima, 0); + if (base_tile->gen_type == IMA_GENTYPE_BLANK) { uiItemR(col, &imaptr, "generated_color", 0, NULL, ICON_NONE); } } @@ -1211,6 +1212,11 @@ void uiTemplateImageInfo(uiLayout *layout, bContext *C, Image *ima, ImageUser *i ofs += BLI_strncpy_rlen(str + ofs, TIP_(" + Z"), len - ofs); } + eGPUTextureFormat texture_format = IMB_gpu_get_texture_format(ibuf, + ima->flag & IMA_HIGH_BITDEPTH); + const char *texture_format_description = GPU_texture_format_description(texture_format); + ofs += BLI_snprintf_rlen(str + ofs, len - ofs, TIP_(", %s"), texture_format_description); + uiItemL(col, str, ICON_NONE); } diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 4036f859231..78aaf957a87 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -3847,15 +3847,16 @@ void IMAGE_OT_clear_render_border(wmOperatorType *ot) static bool do_fill_tile(PointerRNA *ptr, Image *ima, ImageTile *tile) { - float color[4]; - RNA_float_get_array(ptr, "color", color); - int gen_type = RNA_enum_get(ptr, "generated_type"); - int width = RNA_int_get(ptr, "width"); - int height = RNA_int_get(ptr, "height"); + RNA_float_get_array(ptr, "color", tile->gen_color); + tile->gen_type = RNA_enum_get(ptr, "generated_type"); + tile->gen_x = RNA_int_get(ptr, "width"); + tile->gen_y = RNA_int_get(ptr, "height"); bool is_float = RNA_boolean_get(ptr, "float"); - int planes = RNA_boolean_get(ptr, "alpha") ? 32 : 24; - return BKE_image_fill_tile(ima, tile, width, height, color, gen_type, planes, is_float); + tile->gen_flag = is_float ? IMA_GEN_FLOAT : 0; + tile->gen_depth = RNA_boolean_get(ptr, "alpha") ? 32 : 24; + + return BKE_image_fill_tile(ima, tile); } static void draw_fill_tile(PointerRNA *ptr, uiLayout *layout) diff --git a/source/blender/editors/space_image/image_undo.cc b/source/blender/editors/space_image/image_undo.cc index 0fe0414c177..065641c4051 100644 --- a/source/blender/editors/space_image/image_undo.cc +++ b/source/blender/editors/space_image/image_undo.cc @@ -432,7 +432,7 @@ static void utile_decref(UndoImageTile *utile) /** \name Image Undo Buffer * \{ */ -typedef struct UndoImageBuf { +struct UndoImageBuf { struct UndoImageBuf *next, *prev; /** @@ -454,10 +454,8 @@ typedef struct UndoImageBuf { struct { short source; bool use_float; - char gen_type; } image_state; - -} UndoImageBuf; +}; static UndoImageBuf *ubuf_from_image_no_tiles(Image *image, const ImBuf *ibuf) { @@ -474,7 +472,6 @@ static UndoImageBuf *ubuf_from_image_no_tiles(Image *image, const ImBuf *ibuf) MEM_callocN(sizeof(*ubuf->tiles) * ubuf->tiles_len, __func__)); BLI_strncpy(ubuf->ibuf_name, ibuf->name, sizeof(ubuf->ibuf_name)); - ubuf->image_state.gen_type = image->gen_type; ubuf->image_state.source = image->source; ubuf->image_state.use_float = ibuf->rect_float != nullptr; @@ -552,7 +549,7 @@ static void ubuf_free(UndoImageBuf *ubuf) /** \name Image Undo Handle * \{ */ -typedef struct UndoImageHandle { +struct UndoImageHandle { struct UndoImageHandle *next, *prev; /** Each undo handle refers to a single image which may have multiple buffers. */ @@ -567,8 +564,7 @@ typedef struct UndoImageHandle { * List of #UndoImageBuf's to support multiple buffers per image. */ ListBase buffers; - -} UndoImageHandle; +}; static void uhandle_restore_list(ListBase *undo_handles, bool use_init) { diff --git a/source/blender/editors/space_info/info_stats.cc b/source/blender/editors/space_info/info_stats.cc index 29a7eb150a1..e41ff02254b 100644 --- a/source/blender/editors/space_info/info_stats.cc +++ b/source/blender/editors/space_info/info_stats.cc @@ -439,14 +439,7 @@ static void stats_update(Depsgraph *depsgraph, } else if (ob && (ob->mode & OB_MODE_SCULPT)) { /* Sculpt Mode. */ - if (stats_is_object_dynamic_topology_sculpt(ob)) { - /* Dynamic topology. Do not count all vertices, - * dynamic topology stats are initialized later as part of sculpt stats. */ - } - else { - /* When dynamic topology is not enabled both sculpt stats and scene stats are collected. */ - stats_object_sculpt(ob, stats); - } + stats_object_sculpt(ob, stats); } else { /* Objects. */ diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index badcccca87b..26fddda8c22 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -50,8 +50,8 @@ set(LIB bf_editor_screen ) -if(WITH_COMPOSITOR) - add_definitions(-DWITH_COMPOSITOR) +if(WITH_COMPOSITOR_CPU) + add_definitions(-DWITH_COMPOSITOR_CPU) endif() if(WITH_OPENIMAGEDENOISE) diff --git a/source/blender/editors/space_node/link_drag_search.cc b/source/blender/editors/space_node/link_drag_search.cc index c524de2c55d..9014e36c4e2 100644 --- a/source/blender/editors/space_node/link_drag_search.cc +++ b/source/blender/editors/space_node/link_drag_search.cc @@ -232,6 +232,7 @@ static void link_drag_search_exec_fn(bContext *C, void *arg1, void *arg2) PointerRNA ptr; WM_operator_properties_create_ptr(&ptr, ot); RNA_boolean_set(&ptr, "view2d_edge_pan", true); + RNA_boolean_set(&ptr, "remove_on_cancel", true); WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr, nullptr); WM_operator_properties_free(&ptr); } diff --git a/source/blender/editors/space_node/node_add.cc b/source/blender/editors/space_node/node_add.cc index a89b5444a4d..0d498d07aff 100644 --- a/source/blender/editors/space_node/node_add.cc +++ b/source/blender/editors/space_node/node_add.cc @@ -49,29 +49,48 @@ namespace blender::ed::space_node { /** \name Utilities * \{ */ -bNode *node_add_node(const bContext &C, const char *idname, int type, float locx, float locy) +static void position_node_based_on_mouse(bNode &node, const float2 &location) +{ + node.locx = location.x - NODE_DY * 1.5f / UI_DPI_FAC; + node.locy = location.y + NODE_DY * 0.5f / UI_DPI_FAC; +} + +bNode *add_node(const bContext &C, const StringRef idname, const float2 &location) { SpaceNode &snode = *CTX_wm_space_node(&C); Main &bmain = *CTX_data_main(&C); - bNode *node = nullptr; node_deselect_all(snode); - if (idname) { - node = nodeAddNode(&C, snode.edittree, idname); - } - else { - node = nodeAddStaticNode(&C, snode.edittree, type); - } + const std::string idname_str = idname; + + bNode *node = nodeAddNode(&C, snode.edittree, idname_str.c_str()); BLI_assert(node && node->typeinfo); - /* Position mouse in node header. */ - node->locx = locx - NODE_DY * 1.5f / UI_DPI_FAC; - node->locy = locy + NODE_DY * 0.5f / UI_DPI_FAC; + position_node_based_on_mouse(*node, location); nodeSetSelected(node, true); + ED_node_set_active(&bmain, &snode, snode.edittree, node, nullptr); + + ED_node_tree_propagate_change(&C, &bmain, snode.edittree); + return node; +} + +bNode *add_static_node(const bContext &C, int type, const float2 &location) +{ + SpaceNode &snode = *CTX_wm_space_node(&C); + Main &bmain = *CTX_data_main(&C); + + node_deselect_all(snode); + + bNode *node = nodeAddStaticNode(&C, snode.edittree, type); + BLI_assert(node && node->typeinfo); + position_node_based_on_mouse(*node, location); + + nodeSetSelected(node, true); ED_node_set_active(&bmain, &snode, snode.edittree, node, nullptr); + ED_node_tree_propagate_change(&C, &bmain, snode.edittree); return node; } @@ -338,9 +357,9 @@ static int node_add_group_exec(bContext *C, wmOperator *op) Main *bmain = CTX_data_main(C); SpaceNode *snode = CTX_wm_space_node(C); bNodeTree *ntree = snode->edittree; - bNodeTree *node_group; - if (!(node_group = node_add_group_get_and_poll_group_node_tree(bmain, op, ntree))) { + bNodeTree *node_group = node_add_group_get_and_poll_group_node_tree(bmain, op, ntree); + if (!node_group) { return OPERATOR_CANCELLED; } @@ -352,12 +371,7 @@ static int node_add_group_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - bNode *group_node = node_add_node(*C, - node_idname, - (node_group->type == NTREE_CUSTOM) ? NODE_CUSTOM_GROUP : - NODE_GROUP, - snode->runtime->cursor[0], - snode->runtime->cursor[1]); + bNode *group_node = add_node(*C, node_idname, snode->runtime->cursor); if (!group_node) { BKE_report(op->reports, RPT_WARNING, "Could not add node group"); return OPERATOR_CANCELLED; @@ -445,8 +459,7 @@ static int node_add_object_exec(bContext *C, wmOperator *op) ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); - bNode *object_node = node_add_node( - *C, nullptr, GEO_NODE_OBJECT_INFO, snode->runtime->cursor[0], snode->runtime->cursor[1]); + bNode *object_node = add_static_node(*C, GEO_NODE_OBJECT_INFO, snode->runtime->cursor); if (!object_node) { BKE_report(op->reports, RPT_WARNING, "Could not add node object"); return OPERATOR_CANCELLED; @@ -522,7 +535,7 @@ static int node_add_collection_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); SpaceNode &snode = *CTX_wm_space_node(C); - bNodeTree *ntree = snode.edittree; + bNodeTree &ntree = *snode.edittree; Collection *collection = reinterpret_cast<Collection *>( WM_operator_properties_id_lookup_from_name_or_session_uuid(bmain, op->ptr, ID_GR)); @@ -533,8 +546,7 @@ static int node_add_collection_exec(bContext *C, wmOperator *op) ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); - bNode *collection_node = node_add_node( - *C, nullptr, GEO_NODE_COLLECTION_INFO, snode.runtime->cursor[0], snode.runtime->cursor[1]); + bNode *collection_node = add_static_node(*C, GEO_NODE_COLLECTION_INFO, snode.runtime->cursor); if (!collection_node) { BKE_report(op->reports, RPT_WARNING, "Could not add node collection"); return OPERATOR_CANCELLED; @@ -550,8 +562,8 @@ static int node_add_collection_exec(bContext *C, wmOperator *op) socket_data->value = collection; id_us_plus(&collection->id); - nodeSetActive(ntree, collection_node); - ED_node_tree_propagate_change(C, bmain, ntree); + nodeSetActive(&ntree, collection_node); + ED_node_tree_propagate_change(C, bmain, &ntree); DEG_relations_tag_update(bmain); return OPERATOR_FINISHED; @@ -617,11 +629,9 @@ static int node_add_file_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); SpaceNode &snode = *CTX_wm_space_node(C); - bNode *node; - Image *ima; int type = 0; - ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM); + Image *ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM); if (!ima) { return OPERATOR_CANCELLED; } @@ -645,7 +655,7 @@ static int node_add_file_exec(bContext *C, wmOperator *op) ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); - node = node_add_node(*C, nullptr, type, snode.runtime->cursor[0], snode.runtime->cursor[1]); + bNode *node = add_static_node(*C, type, snode.runtime->cursor); if (!node) { BKE_report(op->reports, RPT_WARNING, "Could not add an image node"); @@ -739,7 +749,6 @@ static int node_add_mask_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); SpaceNode &snode = *CTX_wm_space_node(C); - bNode *node; ID *mask = WM_operator_properties_id_lookup_from_name_or_session_uuid(bmain, op->ptr, ID_MSK); if (!mask) { @@ -748,8 +757,7 @@ static int node_add_mask_exec(bContext *C, wmOperator *op) ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C)); - node = node_add_node( - *C, nullptr, CMP_NODE_MASK, snode.runtime->cursor[0], snode.runtime->cursor[1]); + bNode *node = add_static_node(*C, CMP_NODE_MASK, snode.runtime->cursor); if (!node) { BKE_report(op->reports, RPT_WARNING, "Could not add a mask node"); diff --git a/source/blender/editors/space_node/node_group.cc b/source/blender/editors/space_node/node_group.cc index a926f7e8917..bb520c0537e 100644 --- a/source/blender/editors/space_node/node_group.cc +++ b/source/blender/editors/space_node/node_group.cc @@ -45,7 +45,12 @@ #include "UI_resources.h" #include "NOD_common.h" +#include "NOD_composite.h" +#include "NOD_geometry.h" +#include "NOD_shader.h" #include "NOD_socket.h" +#include "NOD_texture.h" + #include "node_intern.hh" /* own include */ namespace blender::ed::space_node { @@ -100,16 +105,16 @@ const char *node_group_idname(bContext *C) SpaceNode *snode = CTX_wm_space_node(C); if (ED_node_is_shader(snode)) { - return "ShaderNodeGroup"; + return ntreeType_Shader->group_idname; } if (ED_node_is_compositor(snode)) { - return "CompositorNodeGroup"; + return ntreeType_Composite->group_idname; } if (ED_node_is_texture(snode)) { - return "TextureNodeGroup"; + return ntreeType_Texture->group_idname; } if (ED_node_is_geometry(snode)) { - return "GeometryNodeGroup"; + return ntreeType_Geometry->group_idname; } return ""; diff --git a/source/blender/editors/space_node/node_intern.hh b/source/blender/editors/space_node/node_intern.hh index 924537d0e8a..81c2bc0e962 100644 --- a/source/blender/editors/space_node/node_intern.hh +++ b/source/blender/editors/space_node/node_intern.hh @@ -245,12 +245,9 @@ void draw_nodespace_back_pix(const bContext &C, /* node_add.cc */ -/** - * XXX Does some additional initialization on top of #nodeAddNode - * Can be used with both custom and static nodes, - * if `idname == nullptr` the static int type will be used instead. - */ -bNode *node_add_node(const bContext &C, const char *idname, int type, float locx, float locy); +bNode *add_node(const bContext &C, StringRef idname, const float2 &location); +bNode *add_static_node(const bContext &C, int type, const float2 &location); + void NODE_OT_add_reroute(wmOperatorType *ot); void NODE_OT_add_group(wmOperatorType *ot); void NODE_OT_add_object(wmOperatorType *ot); diff --git a/source/blender/editors/space_node/node_relationships.cc b/source/blender/editors/space_node/node_relationships.cc index e10bedb18f4..d911e53be7f 100644 --- a/source/blender/editors/space_node/node_relationships.cc +++ b/source/blender/editors/space_node/node_relationships.cc @@ -639,8 +639,8 @@ static int link_socket_to_viewer(const bContext &C, if (viewer_bnode == nullptr) { /* Create a new viewer node if none exists. */ const int viewer_type = get_default_viewer_type(&C); - viewer_bnode = node_add_node( - C, nullptr, viewer_type, bsocket_to_view.locx + 100, bsocket_to_view.locy); + const float2 location{bsocket_to_view.locx + 100, bsocket_to_view.locy}; + viewer_bnode = add_static_node(C, viewer_type, location); if (viewer_bnode == nullptr) { return OPERATOR_CANCELLED; } @@ -1654,7 +1654,7 @@ static int node_join_exec(bContext *C, wmOperator *UNUSED(op)) SpaceNode &snode = *CTX_wm_space_node(C); bNodeTree &ntree = *snode.edittree; - /* XXX save selection: node_add_node call below sets the new frame as single + /* XXX save selection: add_static_node call below sets the new frame as single * active+selected node */ LISTBASE_FOREACH (bNode *, node, &ntree.nodes) { if (node->flag & NODE_SELECT) { @@ -1665,7 +1665,7 @@ static int node_join_exec(bContext *C, wmOperator *UNUSED(op)) } } - bNode *frame = node_add_node(*C, nullptr, NODE_FRAME, 0.0f, 0.0f); + bNode *frame = add_static_node(*C, NODE_FRAME, float2(0)); /* reset tags */ LISTBASE_FOREACH (bNode *, node, &ntree.nodes) { diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt index 78ec057f921..b9f79303a06 100644 --- a/source/blender/editors/space_outliner/CMakeLists.txt +++ b/source/blender/editors/space_outliner/CMakeLists.txt @@ -48,11 +48,11 @@ set(SRC tree/tree_element_anim_data.cc tree/tree_element_collection.cc tree/tree_element_driver.cc - tree/tree_element_label.cc tree/tree_element_gpencil_layer.cc tree/tree_element_id.cc tree/tree_element_id_library.cc tree/tree_element_id_scene.cc + tree/tree_element_label.cc tree/tree_element_nla.cc tree/tree_element_overrides.cc tree/tree_element_rna.cc @@ -68,11 +68,11 @@ set(SRC tree/tree_element_anim_data.hh tree/tree_element_collection.hh tree/tree_element_driver.hh - tree/tree_element_label.hh tree/tree_element_gpencil_layer.hh tree/tree_element_id.hh tree/tree_element_id_library.hh tree/tree_element_id_scene.hh + tree/tree_element_label.hh tree/tree_element_nla.hh tree/tree_element_overrides.hh tree/tree_element_rna.hh diff --git a/source/blender/editors/space_outliner/outliner_collections.cc b/source/blender/editors/space_outliner/outliner_collections.cc index 8ca2ffe6a9c..7d0a0a921e4 100644 --- a/source/blender/editors/space_outliner/outliner_collections.cc +++ b/source/blender/editors/space_outliner/outliner_collections.cc @@ -72,7 +72,7 @@ Collection *outliner_collection_from_tree_element(const TreeElement *te) } if (tselem->type == TSE_LAYER_COLLECTION) { - LayerCollection *lc = reinterpret_cast<LayerCollection *>(te->directdata); + LayerCollection *lc = static_cast<LayerCollection *>(te->directdata); return lc->collection; } if (ELEM(tselem->type, TSE_SCENE_COLLECTION_BASE, TSE_VIEW_COLLECTION_BASE)) { @@ -88,7 +88,7 @@ Collection *outliner_collection_from_tree_element(const TreeElement *te) TreeTraversalAction outliner_find_selected_collections(TreeElement *te, void *customdata) { - struct IDsSelectedData *data = reinterpret_cast<IDsSelectedData *>(customdata); + struct IDsSelectedData *data = static_cast<IDsSelectedData *>(customdata); TreeStoreElem *tselem = TREESTORE(te); if (outliner_is_collection_tree_element(te)) { @@ -105,7 +105,7 @@ TreeTraversalAction outliner_find_selected_collections(TreeElement *te, void *cu TreeTraversalAction outliner_find_selected_objects(TreeElement *te, void *customdata) { - struct IDsSelectedData *data = reinterpret_cast<IDsSelectedData *>(customdata); + struct IDsSelectedData *data = static_cast<IDsSelectedData *>(customdata); TreeStoreElem *tselem = TREESTORE(te); if (outliner_is_collection_tree_element(te)) { @@ -184,7 +184,7 @@ struct CollectionNewData { static TreeTraversalAction collection_find_selected_to_add(TreeElement *te, void *customdata) { - struct CollectionNewData *data = reinterpret_cast<CollectionNewData *>(customdata); + struct CollectionNewData *data = static_cast<CollectionNewData *>(customdata); Collection *collection = outliner_collection_from_tree_element(te); if (!collection) { @@ -286,7 +286,7 @@ struct CollectionEditData { static TreeTraversalAction collection_find_data_to_edit(TreeElement *te, void *customdata) { - CollectionEditData *data = reinterpret_cast<CollectionEditData *>(customdata); + CollectionEditData *data = static_cast<CollectionEditData *>(customdata); Collection *collection = outliner_collection_from_tree_element(te); if (!collection) { @@ -339,7 +339,7 @@ void outliner_collection_delete( /* Effectively delete the collections. */ GSetIterator collections_to_edit_iter; GSET_ITER (collections_to_edit_iter, data.collections_to_edit) { - Collection *collection = reinterpret_cast<Collection *>( + Collection *collection = static_cast<Collection *>( BLI_gsetIterator_getKey(&collections_to_edit_iter)); /* Test in case collection got deleted as part of another one. */ @@ -444,12 +444,12 @@ struct CollectionObjectsSelectData { static TreeTraversalAction outliner_find_first_selected_layer_collection(TreeElement *te, void *customdata) { - CollectionObjectsSelectData *data = reinterpret_cast<CollectionObjectsSelectData *>(customdata); + CollectionObjectsSelectData *data = static_cast<CollectionObjectsSelectData *>(customdata); TreeStoreElem *tselem = TREESTORE(te); switch (tselem->type) { case TSE_LAYER_COLLECTION: - data->layer_collection = reinterpret_cast<LayerCollection *>(te->directdata); + data->layer_collection = static_cast<LayerCollection *>(te->directdata); return TRAVERSE_BREAK; case TSE_R_LAYER: case TSE_SCENE_COLLECTION_BASE: @@ -538,7 +538,7 @@ struct CollectionDuplicateData { static TreeTraversalAction outliner_find_first_selected_collection(TreeElement *te, void *customdata) { - CollectionDuplicateData *data = reinterpret_cast<CollectionDuplicateData *>(customdata); + CollectionDuplicateData *data = static_cast<CollectionDuplicateData *>(customdata); TreeStoreElem *tselem = TREESTORE(te); switch (tselem->type) { @@ -701,7 +701,7 @@ static int collection_link_exec(bContext *C, wmOperator *op) /* Effectively link the collections. */ GSetIterator collections_to_edit_iter; GSET_ITER (collections_to_edit_iter, data.collections_to_edit) { - Collection *collection = reinterpret_cast<Collection *>( + Collection *collection = static_cast<Collection *>( BLI_gsetIterator_getKey(&collections_to_edit_iter)); BKE_collection_child_add(bmain, active_collection, collection); id_fake_user_clear(&collection->id); @@ -762,7 +762,7 @@ static int collection_instance_exec(bContext *C, wmOperator *UNUSED(op)) GSetIterator collections_to_edit_iter; GSET_ITER (collections_to_edit_iter, data.collections_to_edit) { - Collection *collection = reinterpret_cast<Collection *>( + Collection *collection = static_cast<Collection *>( BLI_gsetIterator_getKey(&collections_to_edit_iter)); while (BKE_collection_cycle_find(active_lc->collection, collection)) { @@ -772,7 +772,7 @@ static int collection_instance_exec(bContext *C, wmOperator *UNUSED(op)) /* Effectively instance the collections. */ GSET_ITER (collections_to_edit_iter, data.collections_to_edit) { - Collection *collection = reinterpret_cast<Collection *>( + Collection *collection = static_cast<Collection *>( BLI_gsetIterator_getKey(&collections_to_edit_iter)); Object *ob = ED_object_add_type( C, OB_EMPTY, collection->id.name + 2, scene->cursor.location, nullptr, false, 0); @@ -814,14 +814,14 @@ void OUTLINER_OT_collection_instance(wmOperatorType *ot) static TreeTraversalAction layer_collection_find_data_to_edit(TreeElement *te, void *customdata) { - CollectionEditData *data = reinterpret_cast<CollectionEditData *>(customdata); + CollectionEditData *data = static_cast<CollectionEditData *>(customdata); TreeStoreElem *tselem = TREESTORE(te); if (!(tselem && tselem->type == TSE_LAYER_COLLECTION)) { return TRAVERSE_CONTINUE; } - LayerCollection *lc = reinterpret_cast<LayerCollection *>(te->directdata); + LayerCollection *lc = static_cast<LayerCollection *>(te->directdata); if (lc->collection->flag & COLLECTION_IS_MASTER) { /* skip - showing warning/error message might be misleading @@ -862,7 +862,7 @@ static bool collections_view_layer_poll(bContext *C, bool clear, int flag) GSetIterator collections_to_edit_iter; GSET_ITER (collections_to_edit_iter, data.collections_to_edit) { - LayerCollection *lc = reinterpret_cast<LayerCollection *>( + LayerCollection *lc = static_cast<LayerCollection *>( BLI_gsetIterator_getKey(&collections_to_edit_iter)); if (clear && (lc->flag & flag)) { @@ -934,7 +934,7 @@ static int collection_view_layer_exec(bContext *C, wmOperator *op) GSetIterator collections_to_edit_iter; GSET_ITER (collections_to_edit_iter, data.collections_to_edit) { - LayerCollection *lc = reinterpret_cast<LayerCollection *>( + LayerCollection *lc = static_cast<LayerCollection *>( BLI_gsetIterator_getKey(&collections_to_edit_iter)); BKE_layer_collection_set_flag(lc, flag, !clear); } @@ -1068,7 +1068,7 @@ static int collection_isolate_exec(bContext *C, wmOperator *op) GSetIterator collections_to_edit_iter; GSET_ITER (collections_to_edit_iter, data.collections_to_edit) { - LayerCollection *layer_collection = reinterpret_cast<LayerCollection *>( + LayerCollection *layer_collection = static_cast<LayerCollection *>( BLI_gsetIterator_getKey(&collections_to_edit_iter)); if (extend) { @@ -1168,7 +1168,7 @@ static int collection_visibility_exec(bContext *C, wmOperator *op) GSetIterator collections_to_edit_iter; GSET_ITER (collections_to_edit_iter, data.collections_to_edit) { - LayerCollection *layer_collection = reinterpret_cast<LayerCollection *>( + LayerCollection *layer_collection = static_cast<LayerCollection *>( BLI_gsetIterator_getKey(&collections_to_edit_iter)); BKE_layer_collection_set_visible(view_layer, layer_collection, show, is_inside); } @@ -1319,7 +1319,7 @@ static int collection_flag_exec(bContext *C, wmOperator *op) &data); GSetIterator collections_to_edit_iter; GSET_ITER (collections_to_edit_iter, data.collections_to_edit) { - LayerCollection *layer_collection = reinterpret_cast<LayerCollection *>( + LayerCollection *layer_collection = static_cast<LayerCollection *>( BLI_gsetIterator_getKey(&collections_to_edit_iter)); Collection *collection = layer_collection->collection; if (!BKE_id_is_editable(bmain, &collection->id)) { @@ -1348,7 +1348,7 @@ static int collection_flag_exec(bContext *C, wmOperator *op) &data); GSetIterator collections_to_edit_iter; GSET_ITER (collections_to_edit_iter, data.collections_to_edit) { - Collection *collection = reinterpret_cast<Collection *>( + Collection *collection = static_cast<Collection *>( BLI_gsetIterator_getKey(&collections_to_edit_iter)); if (!BKE_id_is_editable(bmain, &collection->id)) { continue; @@ -1451,7 +1451,7 @@ struct OutlinerHideEditData { static TreeTraversalAction outliner_hide_find_data_to_edit(TreeElement *te, void *customdata) { - OutlinerHideEditData *data = reinterpret_cast<OutlinerHideEditData *>(customdata); + OutlinerHideEditData *data = static_cast<OutlinerHideEditData *>(customdata); TreeStoreElem *tselem = TREESTORE(te); if (tselem == nullptr) { @@ -1459,7 +1459,7 @@ static TreeTraversalAction outliner_hide_find_data_to_edit(TreeElement *te, void } if (tselem->type == TSE_LAYER_COLLECTION) { - LayerCollection *lc = reinterpret_cast<LayerCollection *>(te->directdata); + LayerCollection *lc = static_cast<LayerCollection *>(te->directdata); if (lc->collection->flag & COLLECTION_IS_MASTER) { /* Skip - showing warning/error message might be misleading @@ -1501,7 +1501,7 @@ static int outliner_hide_exec(bContext *C, wmOperator *UNUSED(op)) GSetIterator collections_to_edit_iter; GSET_ITER (collections_to_edit_iter, data.collections_to_edit) { - LayerCollection *layer_collection = reinterpret_cast<LayerCollection *>( + LayerCollection *layer_collection = static_cast<LayerCollection *>( BLI_gsetIterator_getKey(&collections_to_edit_iter)); BKE_layer_collection_set_visible(view_layer, layer_collection, false, false); } @@ -1509,7 +1509,7 @@ static int outliner_hide_exec(bContext *C, wmOperator *UNUSED(op)) GSetIterator bases_to_edit_iter; GSET_ITER (bases_to_edit_iter, data.bases_to_edit) { - Base *base = reinterpret_cast<Base *>(BLI_gsetIterator_getKey(&bases_to_edit_iter)); + Base *base = static_cast<Base *>(BLI_gsetIterator_getKey(&bases_to_edit_iter)); base->flag |= BASE_HIDDEN; } BLI_gset_free(data.bases_to_edit, nullptr); @@ -1542,8 +1542,7 @@ static int outliner_unhide_all_exec(bContext *C, wmOperator *UNUSED(op)) ViewLayer *view_layer = CTX_data_view_layer(C); /* Unhide all the collections. */ - LayerCollection *lc_master = reinterpret_cast<LayerCollection *>( - view_layer->layer_collections.first); + LayerCollection *lc_master = static_cast<LayerCollection *>(view_layer->layer_collections.first); LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_master->layer_collections) { BKE_layer_collection_set_flag(lc_iter, LAYER_COLLECTION_HIDE, false); } diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.cc b/source/blender/editors/space_outliner/outliner_dragdrop.cc index 7435fa50a93..2fa512b4006 100644 --- a/source/blender/editors/space_outliner/outliner_dragdrop.cc +++ b/source/blender/editors/space_outliner/outliner_dragdrop.cc @@ -144,7 +144,7 @@ static TreeElement *outliner_drop_insert_find(bContext *C, return te_hovered; } *r_insert_type = TE_INSERT_BEFORE; - return reinterpret_cast<TreeElement *>(te_hovered->subtree.first); + return static_cast<TreeElement *>(te_hovered->subtree.first); } *r_insert_type = TE_INSERT_AFTER; return te_hovered; @@ -159,8 +159,8 @@ static TreeElement *outliner_drop_insert_find(bContext *C, /* Mouse doesn't hover any item (ignoring x-axis), * so it's either above list bounds or below. */ - TreeElement *first = reinterpret_cast<TreeElement *>(space_outliner->tree.first); - TreeElement *last = reinterpret_cast<TreeElement *>(space_outliner->tree.last); + TreeElement *first = static_cast<TreeElement *>(space_outliner->tree.first); + TreeElement *last = static_cast<TreeElement *>(space_outliner->tree.last); if (view_mval[1] < last->ys) { *r_insert_type = TE_INSERT_AFTER; @@ -422,12 +422,12 @@ static int parent_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_CANCELLED; } - ListBase *lb = reinterpret_cast<ListBase *>(event->customdata); - wmDrag *drag = reinterpret_cast<wmDrag *>(lb->first); + ListBase *lb = static_cast<ListBase *>(event->customdata); + wmDrag *drag = static_cast<wmDrag *>(lb->first); parent_drop_set_parents(C, op->reports, - reinterpret_cast<wmDragID *>(drag->ids.first), + static_cast<wmDragID *>(drag->ids.first), par, PAR_OBJECT, event->modifier & KM_ALT); @@ -505,8 +505,8 @@ static int parent_clear_invoke(bContext *C, wmOperator *UNUSED(op), const wmEven return OPERATOR_CANCELLED; } - ListBase *lb = reinterpret_cast<ListBase *>(event->customdata); - wmDrag *drag = reinterpret_cast<wmDrag *>(lb->first); + ListBase *lb = static_cast<ListBase *>(event->customdata); + wmDrag *drag = static_cast<wmDrag *>(lb->first); LISTBASE_FOREACH (wmDragID *, drag_id, &drag->ids) { if (GS(drag_id->id->name) == ID_OB) { @@ -849,7 +849,7 @@ static bool datastack_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event) ARegion *region = CTX_wm_region(C); bool changed = outliner_flag_set(*space_outliner, TSE_HIGHLIGHTED_ANY | TSE_DRAG_ANY, false); - StackDropData *drop_data = reinterpret_cast<StackDropData *>(drag->poin); + StackDropData *drop_data = static_cast<StackDropData *>(drag->poin); if (!drop_data) { return false; } @@ -887,7 +887,7 @@ static char *datastack_drop_tooltip(bContext *UNUSED(C), const int UNUSED(xy[2]), struct wmDropBox *UNUSED(drop)) { - StackDropData *drop_data = reinterpret_cast<StackDropData *>(drag->poin); + StackDropData *drop_data = static_cast<StackDropData *>(drag->poin); switch (drop_data->drop_action) { case DATA_STACK_DROP_REORDER: return BLI_strdup(TIP_("Reorder")); @@ -965,14 +965,13 @@ static void datastack_drop_copy(bContext *C, StackDropData *drop_data) case TSE_MODIFIER: if (drop_data->ob_parent->type == OB_GPENCIL && ob_dst->type == OB_GPENCIL) { ED_object_gpencil_modifier_copy_to_object( - ob_dst, reinterpret_cast<GpencilModifierData *>(drop_data->drag_directdata)); + ob_dst, static_cast<GpencilModifierData *>(drop_data->drag_directdata)); } else if (drop_data->ob_parent->type != OB_GPENCIL && ob_dst->type != OB_GPENCIL) { - ED_object_modifier_copy_to_object( - C, - ob_dst, - drop_data->ob_parent, - reinterpret_cast<ModifierData *>(drop_data->drag_directdata)); + ED_object_modifier_copy_to_object(C, + ob_dst, + drop_data->ob_parent, + static_cast<ModifierData *>(drop_data->drag_directdata)); } break; case TSE_CONSTRAINT: @@ -980,12 +979,12 @@ static void datastack_drop_copy(bContext *C, StackDropData *drop_data) ED_object_constraint_copy_for_pose( bmain, ob_dst, - reinterpret_cast<bPoseChannel *>(drop_data->drop_te->directdata), - reinterpret_cast<bConstraint *>(drop_data->drag_directdata)); + static_cast<bPoseChannel *>(drop_data->drop_te->directdata), + static_cast<bConstraint *>(drop_data->drag_directdata)); } else { ED_object_constraint_copy_for_object( - bmain, ob_dst, reinterpret_cast<bConstraint *>(drop_data->drag_directdata)); + bmain, ob_dst, static_cast<bConstraint *>(drop_data->drag_directdata)); } break; case TSE_GPENCIL_EFFECT: { @@ -993,8 +992,7 @@ static void datastack_drop_copy(bContext *C, StackDropData *drop_data) return; } - ED_object_shaderfx_copy(ob_dst, - reinterpret_cast<ShaderFxData *>(drop_data->drag_directdata)); + ED_object_shaderfx_copy(ob_dst, static_cast<ShaderFxData *>(drop_data->drag_directdata)); break; } } @@ -1021,15 +1019,12 @@ static void datastack_drop_reorder(bContext *C, ReportList *reports, StackDropDa index = outliner_get_insert_index( drag_te, drop_te, insert_type, &ob->greasepencil_modifiers); ED_object_gpencil_modifier_move_to_index( - reports, - ob, - reinterpret_cast<GpencilModifierData *>(drop_data->drag_directdata), - index); + reports, ob, static_cast<GpencilModifierData *>(drop_data->drag_directdata), index); } else { index = outliner_get_insert_index(drag_te, drop_te, insert_type, &ob->modifiers); ED_object_modifier_move_to_index( - reports, ob, reinterpret_cast<ModifierData *>(drop_data->drag_directdata), index); + reports, ob, static_cast<ModifierData *>(drop_data->drag_directdata), index); } break; case TSE_CONSTRAINT: @@ -1041,13 +1036,13 @@ static void datastack_drop_reorder(bContext *C, ReportList *reports, StackDropDa index = outliner_get_insert_index(drag_te, drop_te, insert_type, &ob->constraints); } ED_object_constraint_move_to_index( - ob, reinterpret_cast<bConstraint *>(drop_data->drag_directdata), index); + ob, static_cast<bConstraint *>(drop_data->drag_directdata), index); break; case TSE_GPENCIL_EFFECT: index = outliner_get_insert_index(drag_te, drop_te, insert_type, &ob->shader_fx); ED_object_shaderfx_move_to_index( - reports, ob, reinterpret_cast<ShaderFxData *>(drop_data->drag_directdata), index); + reports, ob, static_cast<ShaderFxData *>(drop_data->drag_directdata), index); } } @@ -1057,9 +1052,9 @@ static int datastack_drop_invoke(bContext *C, wmOperator *op, const wmEvent *eve return OPERATOR_CANCELLED; } - ListBase *lb = reinterpret_cast<ListBase *>(event->customdata); - wmDrag *drag = reinterpret_cast<wmDrag *>(lb->first); - StackDropData *drop_data = reinterpret_cast<StackDropData *>(drag->poin); + ListBase *lb = static_cast<ListBase *>(event->customdata); + wmDrag *drag = static_cast<wmDrag *>(lb->first); + StackDropData *drop_data = static_cast<StackDropData *>(drag->poin); switch (drop_data->drop_action) { case DATA_STACK_DROP_LINK: @@ -1143,7 +1138,7 @@ static bool collection_drop_init(bContext *C, wmDrag *drag, const int xy[2], Col return false; } - wmDragID *drag_id = reinterpret_cast<wmDragID *>(drag->ids.first); + wmDragID *drag_id = static_cast<wmDragID *>(drag->ids.first); if (drag_id == nullptr) { return false; } @@ -1300,8 +1295,8 @@ static int collection_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmE return OPERATOR_CANCELLED; } - ListBase *lb = reinterpret_cast<ListBase *>(event->customdata); - wmDrag *drag = reinterpret_cast<wmDrag *>(lb->first); + ListBase *lb = static_cast<ListBase *>(event->customdata); + wmDrag *drag = static_cast<wmDrag *>(lb->first); CollectionDrop data; if (!collection_drop_init(C, drag, event->xy, &data)) { diff --git a/source/blender/editors/space_outliner/outliner_draw.cc b/source/blender/editors/space_outliner/outliner_draw.cc index ae9ffffd145..8bc1ed8c84e 100644 --- a/source/blender/editors/space_outliner/outliner_draw.cc +++ b/source/blender/editors/space_outliner/outliner_draw.cc @@ -277,8 +277,8 @@ static void outliner_object_set_flag_recursive_fn(bContext *C, Object *ob_parent = ob ? ob : base->object; - for (Object *ob_iter = reinterpret_cast<Object *>(bmain->objects.first); ob_iter; - ob_iter = reinterpret_cast<Object *>(ob_iter->id.next)) { + for (Object *ob_iter = static_cast<Object *>(bmain->objects.first); ob_iter; + ob_iter = static_cast<Object *>(ob_iter->id.next)) { if (BKE_object_is_child_recursive(ob_parent, ob_iter)) { if (ob) { RNA_id_pointer_create(&ob_iter->id, &ptr); @@ -312,8 +312,8 @@ static void outliner_object_set_flag_recursive_fn(bContext *C, */ static void outliner__object_set_flag_recursive_fn(bContext *C, void *poin, void *poin2) { - Object *ob = reinterpret_cast<Object *>(poin); - char *propname = reinterpret_cast<char *>(poin2); + Object *ob = static_cast<Object *>(poin); + char *propname = static_cast<char *>(poin2); outliner_object_set_flag_recursive_fn(C, nullptr, ob, propname); } @@ -322,8 +322,8 @@ static void outliner__object_set_flag_recursive_fn(bContext *C, void *poin, void */ static void outliner__base_set_flag_recursive_fn(bContext *C, void *poin, void *poin2) { - Base *base = reinterpret_cast<Base *>(poin); - char *propname = reinterpret_cast<char *>(poin2); + Base *base = static_cast<Base *>(poin); + char *propname = static_cast<char *>(poin2); outliner_object_set_flag_recursive_fn(C, base, nullptr, propname); } @@ -488,7 +488,7 @@ void outliner_collection_isolate_flag(Scene *scene, const bool is_hide = strstr(propname, "hide_") != nullptr; LayerCollection *top_layer_collection = layer_collection ? - reinterpret_cast<LayerCollection *>( + static_cast<LayerCollection *>( view_layer->layer_collections.first) : nullptr; Collection *top_collection = collection ? scene->master_collection : nullptr; @@ -559,7 +559,7 @@ void outliner_collection_isolate_flag(Scene *scene, else { CollectionParent *parent; Collection *child = collection; - while ((parent = reinterpret_cast<CollectionParent *>(child->parents.first))) { + while ((parent = static_cast<CollectionParent *>(child->parents.first))) { if (parent->collection->flag & COLLECTION_IS_MASTER) { break; } @@ -638,8 +638,8 @@ static void view_layer__layer_collection_set_flag_recursive_fn(bContext *C, void *poin, void *poin2) { - LayerCollection *layer_collection = reinterpret_cast<LayerCollection *>(poin); - char *propname = reinterpret_cast<char *>(poin2); + LayerCollection *layer_collection = static_cast<LayerCollection *>(poin); + char *propname = static_cast<char *>(poin2); outliner_collection_set_flag_recursive_fn(C, layer_collection, nullptr, propname); } @@ -649,8 +649,8 @@ static void view_layer__layer_collection_set_flag_recursive_fn(bContext *C, */ static void view_layer__collection_set_flag_recursive_fn(bContext *C, void *poin, void *poin2) { - LayerCollection *layer_collection = reinterpret_cast<LayerCollection *>(poin); - char *propname = reinterpret_cast<char *>(poin2); + LayerCollection *layer_collection = static_cast<LayerCollection *>(poin); + char *propname = static_cast<char *>(poin2); outliner_collection_set_flag_recursive_fn( C, layer_collection, layer_collection->collection, propname); } @@ -661,8 +661,8 @@ static void view_layer__collection_set_flag_recursive_fn(bContext *C, void *poin */ static void scenes__collection_set_flag_recursive_fn(bContext *C, void *poin, void *poin2) { - Collection *collection = reinterpret_cast<Collection *>(poin); - char *propname = reinterpret_cast<char *>(poin2); + Collection *collection = static_cast<Collection *>(poin); + char *propname = static_cast<char *>(poin2); outliner_collection_set_flag_recursive_fn(C, nullptr, collection, propname); } @@ -672,7 +672,7 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname) SpaceOutliner *space_outliner = CTX_wm_space_outliner(C); struct wmMsgBus *mbus = CTX_wm_message_bus(C); BLI_mempool *ts = space_outliner->treestore; - TreeStoreElem *tselem = reinterpret_cast<TreeStoreElem *>(tsep); + TreeStoreElem *tselem = static_cast<TreeStoreElem *>(tsep); if (ts && tselem) { TreeElement *te = outliner_find_tree_element(&space_outliner->tree, tselem); @@ -737,7 +737,7 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname) switch (tselem->type) { case TSE_DEFGROUP: { Object *ob = (Object *)tselem->id; - bDeformGroup *vg = reinterpret_cast<bDeformGroup *>(te->directdata); + bDeformGroup *vg = static_cast<bDeformGroup *>(te->directdata); BKE_object_defgroup_unique_name(vg, ob); WM_msg_publish_rna_prop(mbus, &ob->id, vg, VertexGroup, name); break; @@ -752,7 +752,7 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname) case TSE_EBONE: { bArmature *arm = (bArmature *)tselem->id; if (arm->edbo) { - EditBone *ebone = reinterpret_cast<EditBone *>(te->directdata); + EditBone *ebone = static_cast<EditBone *>(te->directdata); char newname[sizeof(ebone->name)]; /* restore bone name */ @@ -770,7 +770,7 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname) outliner_viewcontext_init(C, &tvc); bArmature *arm = (bArmature *)tselem->id; - Bone *bone = reinterpret_cast<Bone *>(te->directdata); + Bone *bone = static_cast<Bone *>(te->directdata); char newname[sizeof(bone->name)]; /* always make current object active */ @@ -790,7 +790,7 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname) Object *ob = (Object *)tselem->id; bArmature *arm = (bArmature *)ob->data; - bPoseChannel *pchan = reinterpret_cast<bPoseChannel *>(te->directdata); + bPoseChannel *pchan = static_cast<bPoseChannel *>(te->directdata); char newname[sizeof(pchan->name)]; /* always make current pose-bone active */ @@ -801,15 +801,14 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname) /* restore bone name */ BLI_strncpy(newname, pchan->name, sizeof(pchan->name)); BLI_strncpy(pchan->name, oldname, sizeof(pchan->name)); - ED_armature_bone_rename( - bmain, reinterpret_cast<bArmature *>(ob->data), oldname, newname); + ED_armature_bone_rename(bmain, static_cast<bArmature *>(ob->data), oldname, newname); WM_msg_publish_rna_prop(mbus, &arm->id, pchan->bone, Bone, name); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, nullptr); break; } case TSE_POSEGRP: { Object *ob = (Object *)tselem->id; /* id = object. */ - bActionGroup *grp = reinterpret_cast<bActionGroup *>(te->directdata); + bActionGroup *grp = static_cast<bActionGroup *>(te->directdata); BLI_uniquename(&ob->pose->agroups, grp, @@ -823,7 +822,7 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname) } case TSE_GP_LAYER: { bGPdata *gpd = (bGPdata *)tselem->id; /* id = GP Datablock */ - bGPDlayer *gpl = reinterpret_cast<bGPDlayer *>(te->directdata); + bGPDlayer *gpl = static_cast<bGPDlayer *>(te->directdata); /* always make layer active */ BKE_gpencil_layer_active_set(gpd, gpl); @@ -839,7 +838,7 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname) } case TSE_R_LAYER: { Scene *scene = (Scene *)tselem->id; - ViewLayer *view_layer = reinterpret_cast<ViewLayer *>(te->directdata); + ViewLayer *view_layer = static_cast<ViewLayer *>(te->directdata); /* Restore old name. */ char newname[sizeof(view_layer->name)]; @@ -991,7 +990,7 @@ static bool outliner_restrict_properties_collection_set(Scene *scene, { TreeStoreElem *tselem = TREESTORE(te); LayerCollection *layer_collection = (tselem->type == TSE_LAYER_COLLECTION) ? - reinterpret_cast<LayerCollection *>(te->directdata) : + static_cast<LayerCollection *>(te->directdata) : nullptr; Collection *collection = outliner_collection_from_tree_element(te); @@ -1105,7 +1104,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, ELEM(space_outliner->outlinevis, SO_SCENES, SO_VIEW_LAYER)) { if (space_outliner->show_restrict_flags & SO_RESTRICT_RENDER) { /* View layer render toggle. */ - ViewLayer *layer = reinterpret_cast<ViewLayer *>(te->directdata); + ViewLayer *layer = static_cast<ViewLayer *>(te->directdata); bt = uiDefIconButBitS(block, UI_BTYPE_ICON_TOGGLE_N, @@ -1329,7 +1328,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, bPoseChannel *pchan = (bPoseChannel *)te->directdata; Bone *bone = pchan->bone; Object *ob = (Object *)tselem->id; - bArmature *arm = reinterpret_cast<bArmature *>(ob->data); + bArmature *arm = static_cast<bArmature *>(ob->data); RNA_pointer_create(&arm->id, &RNA_Bone, bone, &ptr); @@ -1479,8 +1478,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, scene, te, &collection_ptr, &layer_collection_ptr, &props, &props_active)) { LayerCollection *layer_collection = (tselem->type == TSE_LAYER_COLLECTION) ? - reinterpret_cast<LayerCollection *>( - te->directdata) : + static_cast<LayerCollection *>(te->directdata) : nullptr; Collection *collection = outliner_collection_from_tree_element(te); @@ -2518,7 +2516,7 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) data.drag_id = tselem->id; break; case TSE_CONSTRAINT: { - bConstraint *con = reinterpret_cast<bConstraint *>(te->directdata); + bConstraint *con = static_cast<bConstraint *>(te->directdata); data.drag_id = tselem->id; switch ((eBConstraint_Types)con->type) { case CONSTRAINT_TYPE_CAMERASOLVER: @@ -2635,9 +2633,8 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) data.drag_id = tselem->id; if (ob->type != OB_GPENCIL) { - ModifierData *md = reinterpret_cast<ModifierData *>( - BLI_findlink(&ob->modifiers, tselem->nr)); - const ModifierTypeInfo *modifier_type = reinterpret_cast<const ModifierTypeInfo *>( + ModifierData *md = static_cast<ModifierData *>(BLI_findlink(&ob->modifiers, tselem->nr)); + const ModifierTypeInfo *modifier_type = static_cast<const ModifierTypeInfo *>( BKE_modifier_get_info((ModifierType)md->type)); if (modifier_type != nullptr) { data.icon = modifier_type->icon; @@ -2648,7 +2645,7 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) } else { /* grease pencil modifiers */ - GpencilModifierData *md = reinterpret_cast<GpencilModifierData *>( + GpencilModifierData *md = static_cast<GpencilModifierData *>( BLI_findlink(&ob->greasepencil_modifiers, tselem->nr)); switch ((GpencilModifierType)md->type) { case eGpencilModifierType_Noise: @@ -2807,7 +2804,7 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te) const PointerRNA &ptr = te_rna_struct->getPointerRNA(); if (RNA_struct_is_ID(ptr.type)) { - data.drag_id = reinterpret_cast<ID *>(ptr.data); + data.drag_id = static_cast<ID *>(ptr.data); data.icon = RNA_struct_ui_icon(ptr.type); } else { diff --git a/source/blender/editors/space_outliner/outliner_edit.cc b/source/blender/editors/space_outliner/outliner_edit.cc index 16da4f7b1dd..f22db5d20fc 100644 --- a/source/blender/editors/space_outliner/outliner_edit.cc +++ b/source/blender/editors/space_outliner/outliner_edit.cc @@ -598,9 +598,9 @@ static int outliner_id_remap_exec(bContext *C, wmOperator *op) SpaceOutliner *space_outliner = CTX_wm_space_outliner(C); const short id_type = (short)RNA_enum_get(op->ptr, "id_type"); - ID *old_id = reinterpret_cast<ID *>( + ID *old_id = static_cast<ID *>( BLI_findlink(which_libbase(CTX_data_main(C), id_type), RNA_enum_get(op->ptr, "old_id"))); - ID *new_id = reinterpret_cast<ID *>( + ID *new_id = static_cast<ID *>( BLI_findlink(which_libbase(CTX_data_main(C), id_type), RNA_enum_get(op->ptr, "new_id"))); /* check for invalid states */ @@ -694,9 +694,9 @@ static const EnumPropertyItem *outliner_id_itemf(bContext *C, int i = 0; short id_type = (short)RNA_enum_get(ptr, "id_type"); - ID *id = reinterpret_cast<ID *>(which_libbase(CTX_data_main(C), id_type)->first); + ID *id = static_cast<ID *>(which_libbase(CTX_data_main(C), id_type)->first); - for (; id; id = reinterpret_cast<ID *>(id->next)) { + for (; id; id = static_cast<ID *>(id->next)) { item_tmp.identifier = item_tmp.name = id->name + 2; item_tmp.value = i++; RNA_enum_item_add(&item, &totitem, &item_tmp); @@ -1818,7 +1818,7 @@ static void tree_element_to_path(TreeElement *te, /* ptr->data not ptr->owner_id seems to be the one we want, * since ptr->data is sometimes the owner of this ID? */ if (RNA_struct_is_ID(ptr.type)) { - *id = reinterpret_cast<ID *>(ptr.data); + *id = static_cast<ID *>(ptr.data); /* clear path */ if (*path) { @@ -2053,8 +2053,7 @@ static KeyingSet *verify_active_keyingset(Scene *scene, short add) /* try to find one from scene */ if (scene->active_keyingset > 0) { - ks = reinterpret_cast<KeyingSet *>( - BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1)); + ks = static_cast<KeyingSet *>(BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1)); } /* Add if none found */ diff --git a/source/blender/editors/space_outliner/outliner_select.cc b/source/blender/editors/space_outliner/outliner_select.cc index 877e0fc325c..31ae4aef7ff 100644 --- a/source/blender/editors/space_outliner/outliner_select.cc +++ b/source/blender/editors/space_outliner/outliner_select.cc @@ -220,7 +220,7 @@ static void tree_element_viewlayer_activate(bContext *C, TreeElement *te) return; } - ViewLayer *view_layer = reinterpret_cast<ViewLayer *>(te->directdata); + ViewLayer *view_layer = static_cast<ViewLayer *>(te->directdata); wmWindow *win = CTX_wm_window(C); Scene *scene = WM_window_get_active_scene(win); @@ -239,7 +239,7 @@ static void do_outliner_object_select_recursive(ViewLayer *view_layer, { Base *base; - for (base = reinterpret_cast<Base *>(FIRSTBASE(view_layer)); base; base = base->next) { + for (base = static_cast<Base *>(FIRSTBASE(view_layer)); base; base = base->next) { Object *ob = base->object; if ((((base->flag & BASE_VISIBLE_DEPSGRAPH) != 0) && BKE_object_is_child_recursive(ob_parent, ob))) { @@ -418,7 +418,7 @@ static void tree_element_camera_activate(bContext *C, Scene *scene, TreeElement scene->camera = ob; Main *bmain = CTX_data_main(C); - wmWindowManager *wm = reinterpret_cast<wmWindowManager *>(bmain->wm.first); + wmWindowManager *wm = static_cast<wmWindowManager *>(bmain->wm.first); WM_windows_scene_data_sync(&wm->windows, scene); DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE); @@ -458,7 +458,7 @@ static void tree_element_defgroup_activate(bContext *C, TreeElement *te, TreeSto static void tree_element_gplayer_activate(bContext *C, TreeElement *te, TreeStoreElem *tselem) { bGPdata *gpd = (bGPdata *)tselem->id; - bGPDlayer *gpl = reinterpret_cast<bGPDlayer *>(te->directdata); + bGPDlayer *gpl = static_cast<bGPDlayer *>(te->directdata); /* We can only have a single "active" layer at a time * and there must always be an active layer... */ @@ -486,8 +486,8 @@ static void tree_element_posechannel_activate(bContext *C, bool recursive) { Object *ob = (Object *)tselem->id; - bArmature *arm = reinterpret_cast<bArmature *>(ob->data); - bPoseChannel *pchan = reinterpret_cast<bPoseChannel *>(te->directdata); + bArmature *arm = static_cast<bArmature *>(ob->data); + bPoseChannel *pchan = static_cast<bPoseChannel *>(te->directdata); if (!(pchan->bone->flag & BONE_HIDDEN_P)) { if (set != OL_SETSEL_EXTEND) { @@ -508,7 +508,7 @@ static void tree_element_posechannel_activate(bContext *C, } if (ob != ob_iter) { - DEG_id_tag_update(reinterpret_cast<ID *>(ob_iter->data), ID_RECALC_SELECT); + DEG_id_tag_update(static_cast<ID *>(ob_iter->data), ID_RECALC_SELECT); } } MEM_freeN(objects); @@ -541,14 +541,14 @@ static void tree_element_bone_activate(bContext *C, bool recursive) { bArmature *arm = (bArmature *)tselem->id; - Bone *bone = reinterpret_cast<Bone *>(te->directdata); + Bone *bone = static_cast<Bone *>(te->directdata); if (!(bone->flag & BONE_HIDDEN_P)) { Object *ob = OBACT(view_layer); if (ob) { if (set != OL_SETSEL_EXTEND) { /* single select forces all other bones to get unselected */ - for (Bone *bone_iter = reinterpret_cast<Bone *>(arm->bonebase.first); bone_iter != nullptr; + for (Bone *bone_iter = static_cast<Bone *>(arm->bonebase.first); bone_iter != nullptr; bone_iter = bone_iter->next) { bone_iter->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL); do_outliner_bone_select_recursive(arm, bone_iter, false); @@ -590,7 +590,7 @@ static void tree_element_ebone_activate(bContext *C, bool recursive) { bArmature *arm = (bArmature *)tselem->id; - EditBone *ebone = reinterpret_cast<EditBone *>(te->directdata); + EditBone *ebone = static_cast<EditBone *>(te->directdata); if (set == OL_SETSEL_NORMAL) { if (!(ebone->flag & BONE_HIDDEN_A)) { @@ -703,7 +703,7 @@ static void tree_element_sequence_dup_activate(Scene *scene, TreeElement *UNUSED #if 0 select_single_seq(seq, 1); #endif - Sequence *p = reinterpret_cast<Sequence *>(ed->seqbasep->first); + Sequence *p = static_cast<Sequence *>(ed->seqbasep->first); while (p) { if ((!p->strip) || (!p->strip->stripdata) || (p->strip->stripdata->name[0] == '\0')) { p = p->next; @@ -722,7 +722,7 @@ static void tree_element_sequence_dup_activate(Scene *scene, TreeElement *UNUSED static void tree_element_master_collection_activate(const bContext *C) { ViewLayer *view_layer = CTX_data_view_layer(C); - LayerCollection *layer_collection = reinterpret_cast<LayerCollection *>( + LayerCollection *layer_collection = static_cast<LayerCollection *>( view_layer->layer_collections.first); BKE_layer_collection_activate(view_layer, layer_collection); /* A very precise notifier - ND_LAYER alone is quite vague, we want to avoid unnecessary work @@ -733,7 +733,7 @@ static void tree_element_master_collection_activate(const bContext *C) static void tree_element_layer_collection_activate(bContext *C, TreeElement *te) { Scene *scene = CTX_data_scene(C); - LayerCollection *layer_collection = reinterpret_cast<LayerCollection *>(te->directdata); + LayerCollection *layer_collection = static_cast<LayerCollection *>(te->directdata); ViewLayer *view_layer = BKE_view_layer_find_from_collection(scene, layer_collection); BKE_layer_collection_activate(view_layer, layer_collection); /* A very precise notifier - ND_LAYER alone is quite vague, we want to avoid unnecessary work @@ -857,7 +857,7 @@ static eOLDrawState tree_element_bone_state_get(const ViewLayer *view_layer, const TreeStoreElem *tselem) { const bArmature *arm = (const bArmature *)tselem->id; - const Bone *bone = reinterpret_cast<Bone *>(te->directdata); + const Bone *bone = static_cast<Bone *>(te->directdata); const Object *ob = OBACT(view_layer); if (ob && ob->data == arm) { if (bone->flag & BONE_SELECTED) { @@ -869,7 +869,7 @@ static eOLDrawState tree_element_bone_state_get(const ViewLayer *view_layer, static eOLDrawState tree_element_ebone_state_get(const TreeElement *te) { - const EditBone *ebone = reinterpret_cast<EditBone *>(te->directdata); + const EditBone *ebone = static_cast<EditBone *>(te->directdata); if (ebone->flag & BONE_SELECTED) { return OL_DRAWSEL_NORMAL; } @@ -913,7 +913,7 @@ static eOLDrawState tree_element_posechannel_state_get(const Object *ob_pose, const TreeStoreElem *tselem) { const Object *ob = (const Object *)tselem->id; - const bPoseChannel *pchan = reinterpret_cast<bPoseChannel *>(te->directdata); + const bPoseChannel *pchan = static_cast<bPoseChannel *>(te->directdata); if (ob == ob_pose && ob->pose) { if (pchan->bone->flag & BONE_SELECTED) { return OL_DRAWSEL_NORMAL; @@ -929,7 +929,7 @@ static eOLDrawState tree_element_viewlayer_state_get(const bContext *C, const Tr return OL_DRAWSEL_NONE; } - const ViewLayer *view_layer = reinterpret_cast<ViewLayer *>(te->directdata); + const ViewLayer *view_layer = static_cast<ViewLayer *>(te->directdata); if (CTX_data_view_layer(C) == view_layer) { return OL_DRAWSEL_NORMAL; @@ -1229,7 +1229,7 @@ static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreE /* Expand the selected constraint in the properties editor. */ if (tselem->type != TSE_CONSTRAINT_BASE) { - BKE_constraint_panel_expand(reinterpret_cast<bConstraint *>(te->directdata)); + BKE_constraint_panel_expand(static_cast<bConstraint *>(te->directdata)); } break; } @@ -1242,8 +1242,7 @@ static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreE Object *ob = (Object *)tselem->id; if (ob->type == OB_GPENCIL) { - BKE_gpencil_modifier_panel_expand( - reinterpret_cast<GpencilModifierData *>(te->directdata)); + BKE_gpencil_modifier_panel_expand(static_cast<GpencilModifierData *>(te->directdata)); } else { ModifierData *md = (ModifierData *)te->directdata; @@ -1276,12 +1275,12 @@ static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreE context = BCONTEXT_SHADERFX; if (tselem->type != TSE_GPENCIL_EFFECT_BASE) { - BKE_shaderfx_panel_expand(reinterpret_cast<ShaderFxData *>(te->directdata)); + BKE_shaderfx_panel_expand(static_cast<ShaderFxData *>(te->directdata)); } break; case TSE_BONE: { bArmature *arm = (bArmature *)tselem->id; - Bone *bone = reinterpret_cast<Bone *>(te->directdata); + Bone *bone = static_cast<Bone *>(te->directdata); RNA_pointer_create(&arm->id, &RNA_Bone, bone, &ptr); context = BCONTEXT_BONE; @@ -1289,7 +1288,7 @@ static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreE } case TSE_EBONE: { bArmature *arm = (bArmature *)tselem->id; - EditBone *ebone = reinterpret_cast<EditBone *>(te->directdata); + EditBone *ebone = static_cast<EditBone *>(te->directdata); RNA_pointer_create(&arm->id, &RNA_EditBone, ebone, &ptr); context = BCONTEXT_BONE; @@ -1297,8 +1296,8 @@ static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreE } case TSE_POSE_CHANNEL: { Object *ob = (Object *)tselem->id; - bArmature *arm = reinterpret_cast<bArmature *>(ob->data); - bPoseChannel *pchan = reinterpret_cast<bPoseChannel *>(te->directdata); + bArmature *arm = static_cast<bArmature *>(ob->data); + bPoseChannel *pchan = static_cast<bPoseChannel *>(te->directdata); RNA_pointer_create(&arm->id, &RNA_PoseBone, pchan, &ptr); context = BCONTEXT_BONE; @@ -1306,7 +1305,7 @@ static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreE } case TSE_POSE_BASE: { Object *ob = (Object *)tselem->id; - bArmature *arm = reinterpret_cast<bArmature *>(ob->data); + bArmature *arm = static_cast<bArmature *>(ob->data); RNA_pointer_create(&arm->id, &RNA_Armature, arm, &ptr); context = BCONTEXT_DATA; @@ -1314,7 +1313,7 @@ static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreE } case TSE_R_LAYER_BASE: case TSE_R_LAYER: { - ViewLayer *view_layer = reinterpret_cast<ViewLayer *>(te->directdata); + ViewLayer *view_layer = static_cast<ViewLayer *>(te->directdata); RNA_pointer_create(tselem->id, &RNA_ViewLayer, view_layer, &ptr); context = BCONTEXT_VIEW_LAYER; @@ -1323,7 +1322,7 @@ static void outliner_set_properties_tab(bContext *C, TreeElement *te, TreeStoreE case TSE_POSEGRP_BASE: case TSE_POSEGRP: { Object *ob = (Object *)tselem->id; - bArmature *arm = reinterpret_cast<bArmature *>(ob->data); + bArmature *arm = static_cast<bArmature *>(ob->data); RNA_pointer_create(&arm->id, &RNA_Armature, arm, &ptr); context = BCONTEXT_DATA; @@ -1823,7 +1822,7 @@ static TreeElement *outliner_find_rightmost_visible_child(SpaceOutliner *space_o { while (te->subtree.last) { if (TSELEM_OPEN(TREESTORE(te), space_outliner)) { - te = reinterpret_cast<TreeElement *>(te->subtree.last); + te = static_cast<TreeElement *>(te->subtree.last); } else { break; @@ -1867,7 +1866,7 @@ static TreeElement *outliner_find_next_element(SpaceOutliner *space_outliner, Tr TreeStoreElem *tselem = TREESTORE(te); if (TSELEM_OPEN(tselem, space_outliner) && te->subtree.first) { - te = reinterpret_cast<TreeElement *>(te->subtree.first); + te = static_cast<TreeElement *>(te->subtree.first); } else if (te->next) { te = te->next; @@ -1904,7 +1903,7 @@ static TreeElement *outliner_walk_right(SpaceOutliner *space_outliner, /* Only walk down a level if the element is open and not toggling expand */ if (!toggle_all && TSELEM_OPEN(tselem, space_outliner) && !BLI_listbase_is_empty(&te->subtree)) { - te = reinterpret_cast<TreeElement *>(te->subtree.first); + te = static_cast<TreeElement *>(te->subtree.first); } else { outliner_item_openclose(space_outliner, te, true, toggle_all); @@ -1955,7 +1954,7 @@ static TreeElement *find_walk_select_start_element(SpaceOutliner *space_outliner /* If no active element exists, use the first element in the tree */ if (!active_te) { - active_te = reinterpret_cast<TreeElement *>(space_outliner->tree.first); + active_te = static_cast<TreeElement *>(space_outliner->tree.first); *changed = true; } diff --git a/source/blender/editors/space_outliner/outliner_sync.cc b/source/blender/editors/space_outliner/outliner_sync.cc index 36bc7c31b91..772a5826f9f 100644 --- a/source/blender/editors/space_outliner/outliner_sync.cc +++ b/source/blender/editors/space_outliner/outliner_sync.cc @@ -77,8 +77,8 @@ void ED_outliner_select_sync_flag_outliners(const bContext *C) Main *bmain = CTX_data_main(C); wmWindowManager *wm = CTX_wm_manager(C); - for (bScreen *screen = reinterpret_cast<bScreen *>(bmain->screens.first); screen; - screen = reinterpret_cast<bScreen *>(screen->id.next)) { + for (bScreen *screen = static_cast<bScreen *>(bmain->screens.first); screen; + screen = static_cast<bScreen *>(screen->id.next)) { LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) { LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) { if (sl->spacetype == SPACE_OUTLINER) { @@ -259,7 +259,7 @@ static void outliner_select_sync_to_pose_bone(TreeElement *te, GSet *selected_pbones) { Object *ob = (Object *)tselem->id; - bArmature *arm = reinterpret_cast<bArmature *>(ob->data); + bArmature *arm = static_cast<bArmature *>(ob->data); bPoseChannel *pchan = (bPoseChannel *)te->directdata; short bone_flag = pchan->bone->flag; diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc index 87604818ee1..c408eca654c 100644 --- a/source/blender/editors/space_outliner/outliner_tools.cc +++ b/source/blender/editors/space_outliner/outliner_tools.cc @@ -856,7 +856,7 @@ static void id_override_library_create_hierarchy_pre_process_fn(bContext *C, { BLI_assert(TSE_IS_REAL_ID(tselem)); - OutlinerLibOverrideData *data = reinterpret_cast<OutlinerLibOverrideData *>(user_data); + OutlinerLibOverrideData *data = static_cast<OutlinerLibOverrideData *>(user_data); const bool do_hierarchy = data->do_hierarchy; ID *id_root_reference = tselem->id; @@ -1160,7 +1160,7 @@ static void id_override_library_reset_fn(bContext *C, { BLI_assert(TSE_IS_REAL_ID(tselem)); ID *id_root = tselem->id; - OutlinerLibOverrideData *data = reinterpret_cast<OutlinerLibOverrideData *>(user_data); + OutlinerLibOverrideData *data = static_cast<OutlinerLibOverrideData *>(user_data); const bool do_hierarchy = data->do_hierarchy; if (ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) { @@ -1191,7 +1191,7 @@ static void id_override_library_resync_fn(bContext *C, { BLI_assert(TSE_IS_REAL_ID(tselem)); ID *id_root = tselem->id; - OutlinerLibOverrideData *data = reinterpret_cast<OutlinerLibOverrideData *>(user_data); + OutlinerLibOverrideData *data = static_cast<OutlinerLibOverrideData *>(user_data); const bool do_hierarchy_enforce = data->do_resync_hierarchy_enforce; if (ID_IS_OVERRIDE_LIBRARY_REAL(id_root)) { @@ -1637,7 +1637,7 @@ static void data_select_linked_fn(int event, const PointerRNA &ptr = te_rna_struct->getPointerRNA(); if (RNA_struct_is_ID(ptr.type)) { bContext *C = (bContext *)C_v; - ID *id = reinterpret_cast<ID *>(ptr.data); + ID *id = static_cast<ID *>(ptr.data); ED_object_select_linked_by_id(C, id); } @@ -1646,7 +1646,7 @@ static void data_select_linked_fn(int event, static void constraint_fn(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem), void *C_v) { - bContext *C = reinterpret_cast<bContext *>(C_v); + bContext *C = static_cast<bContext *>(C_v); Main *bmain = CTX_data_main(C); bConstraint *constraint = (bConstraint *)te->directdata; Object *ob = (Object *)outliner_search_back(te, ID_OB); @@ -1737,7 +1737,7 @@ static Base *outliner_batch_delete_hierarchy( } object = base->object; - for (child_base = reinterpret_cast<Base *>(view_layer->object_bases.first); child_base; + for (child_base = static_cast<Base *>(view_layer->object_bases.first); child_base; child_base = base_next) { base_next = child_base->next; for (parent = child_base->object->parent; parent && (parent != object); @@ -1960,7 +1960,7 @@ static void outliner_do_object_delete(bContext *C, static TreeTraversalAction outliner_find_objects_to_delete(TreeElement *te, void *customdata) { - ObjectEditData *data = reinterpret_cast<ObjectEditData *>(customdata); + ObjectEditData *data = static_cast<ObjectEditData *>(customdata); GSet *objects_to_delete = data->objects_set; TreeStoreElem *tselem = TREESTORE(te); @@ -2711,8 +2711,7 @@ static int outliner_action_set_exec(bContext *C, wmOperator *op) get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel); /* get action to use */ - act = reinterpret_cast<bAction *>( - BLI_findlink(&bmain->actions, RNA_enum_get(op->ptr, "action"))); + act = static_cast<bAction *>(BLI_findlink(&bmain->actions, RNA_enum_get(op->ptr, "action"))); if (act == nullptr) { BKE_report(op->reports, RPT_ERROR, "No valid action to add"); diff --git a/source/blender/editors/space_outliner/outliner_tree.cc b/source/blender/editors/space_outliner/outliner_tree.cc index 3357a456e30..0906bbb5797 100644 --- a/source/blender/editors/space_outliner/outliner_tree.cc +++ b/source/blender/editors/space_outliner/outliner_tree.cc @@ -90,7 +90,7 @@ static void outliner_storage_cleanup(SpaceOutliner *space_outliner) BLI_mempool_iter iter; BLI_mempool_iternew(ts, &iter); - while ((tselem = reinterpret_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) { + while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) { tselem->used = 0; } @@ -100,7 +100,7 @@ static void outliner_storage_cleanup(SpaceOutliner *space_outliner) space_outliner->storeflag &= ~SO_TREESTORE_CLEANUP; BLI_mempool_iternew(ts, &iter); - while ((tselem = reinterpret_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) { + while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) { if (tselem->id == nullptr) { unused++; } @@ -120,9 +120,9 @@ static void outliner_storage_cleanup(SpaceOutliner *space_outliner) BLI_mempool *new_ts = BLI_mempool_create( sizeof(TreeStoreElem), BLI_mempool_len(ts) - unused, 512, BLI_MEMPOOL_ALLOW_ITER); BLI_mempool_iternew(ts, &iter); - while ((tselem = reinterpret_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) { + while ((tselem = static_cast<TreeStoreElem *>(BLI_mempool_iterstep(&iter)))) { if (tselem->id) { - tsenew = reinterpret_cast<TreeStoreElem *>(BLI_mempool_alloc(new_ts)); + tsenew = static_cast<TreeStoreElem *>(BLI_mempool_alloc(new_ts)); *tsenew = *tselem; } } @@ -151,7 +151,7 @@ static void check_persistent( sizeof(TreeStoreElem), 1, 512, BLI_MEMPOOL_ALLOW_ITER); } if (space_outliner->runtime->treehash == nullptr) { - space_outliner->runtime->treehash = reinterpret_cast<GHash *>( + space_outliner->runtime->treehash = static_cast<GHash *>( BKE_outliner_treehash_create_from_treestore(space_outliner->treestore)); } @@ -166,7 +166,7 @@ static void check_persistent( } /* add 1 element to treestore */ - tselem = reinterpret_cast<TreeStoreElem *>(BLI_mempool_alloc(space_outliner->treestore)); + tselem = static_cast<TreeStoreElem *>(BLI_mempool_alloc(space_outliner->treestore)); tselem->type = type; tselem->nr = type ? nr : 0; tselem->id = id; @@ -293,7 +293,7 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner, outliner_add_element(space_outliner, &te->subtree, ob->data, te, TSE_SOME_ID, 0); if (ob->pose) { - bArmature *arm = reinterpret_cast<bArmature *>(ob->data); + bArmature *arm = static_cast<bArmature *>(ob->data); TreeElement *tenla = outliner_add_element( space_outliner, &te->subtree, ob, te, TSE_POSE_BASE, 0); tenla->name = IFACE_("Pose"); @@ -339,7 +339,7 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner, } } /* make hierarchy */ - TreeElement *ten = reinterpret_cast<TreeElement *>(tenla->subtree.first); + TreeElement *ten = static_cast<TreeElement *>(tenla->subtree.first); while (ten) { TreeElement *nten = ten->next, *par; tselem = TREESTORE(ten); @@ -694,15 +694,15 @@ static void outliner_add_id_contents(SpaceOutliner *space_outliner, ebone->temp.p = ten; } /* make hierarchy */ - TreeElement *ten = arm->edbo->first ? reinterpret_cast<TreeElement *>( - ((EditBone *)arm->edbo->first)->temp.p) : - nullptr; + TreeElement *ten = arm->edbo->first ? + static_cast<TreeElement *>(((EditBone *)arm->edbo->first)->temp.p) : + nullptr; while (ten) { TreeElement *nten = ten->next, *par; EditBone *ebone = (EditBone *)ten->directdata; if (ebone->parent) { BLI_remlink(&te->subtree, ten); - par = reinterpret_cast<TreeElement *>(ebone->parent->temp.p); + par = static_cast<TreeElement *>(ebone->parent->temp.p); BLI_addtail(&par->subtree, ten); ten->parent = par; } @@ -805,12 +805,12 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner, short index, const bool expand) { - ID *id = reinterpret_cast<ID *>(idv); + ID *id = static_cast<ID *>(idv); if (ELEM(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) { id = ((PointerRNA *)idv)->owner_id; if (!id) { - id = reinterpret_cast<ID *>(((PointerRNA *)idv)->data); + id = static_cast<ID *>(((PointerRNA *)idv)->data); } } else if (type == TSE_GP_LAYER) { @@ -990,8 +990,8 @@ struct tTreeSort { /* alphabetical comparator, trying to put objects first */ static int treesort_alpha_ob(const void *v1, const void *v2) { - const tTreeSort *x1 = reinterpret_cast<const tTreeSort *>(v1); - const tTreeSort *x2 = reinterpret_cast<const tTreeSort *>(v2); + const tTreeSort *x1 = static_cast<const tTreeSort *>(v1); + const tTreeSort *x2 = static_cast<const tTreeSort *>(v2); /* first put objects last (hierarchy) */ int comp = (x1->idcode == ID_OB); @@ -1029,8 +1029,8 @@ static int treesort_alpha_ob(const void *v1, const void *v2) /* Move children that are not in the collection to the end of the list. */ static int treesort_child_not_in_collection(const void *v1, const void *v2) { - const tTreeSort *x1 = reinterpret_cast<const tTreeSort *>(v1); - const tTreeSort *x2 = reinterpret_cast<const tTreeSort *>(v2); + const tTreeSort *x1 = static_cast<const tTreeSort *>(v1); + const tTreeSort *x2 = static_cast<const tTreeSort *>(v2); /* Among objects first come the ones in the collection, followed by the ones not on it. * This way we can have the dashed lines in a separate style connecting the former. */ @@ -1043,8 +1043,8 @@ static int treesort_child_not_in_collection(const void *v1, const void *v2) /* alphabetical comparator */ static int treesort_alpha(const void *v1, const void *v2) { - const tTreeSort *x1 = reinterpret_cast<const tTreeSort *>(v1); - const tTreeSort *x2 = reinterpret_cast<const tTreeSort *>(v2); + const tTreeSort *x1 = static_cast<const tTreeSort *>(v1); + const tTreeSort *x2 = static_cast<const tTreeSort *>(v2); int comp = BLI_strcasecmp_natural(x1->name, x2->name); @@ -1101,7 +1101,7 @@ static int treesort_obtype_alpha(const void *v1, const void *v2) /* sort happens on each subtree individual */ static void outliner_sort(ListBase *lb) { - TreeElement *last_te = reinterpret_cast<TreeElement *>(lb->last); + TreeElement *last_te = static_cast<TreeElement *>(lb->last); if (last_te == nullptr) { return; } @@ -1113,7 +1113,7 @@ static void outliner_sort(ListBase *lb) int totelem = BLI_listbase_count(lb); if (totelem > 1) { - tTreeSort *tear = reinterpret_cast<tTreeSort *>( + tTreeSort *tear = static_cast<tTreeSort *>( MEM_mallocN(totelem * sizeof(tTreeSort), "tree sort array")); tTreeSort *tp = tear; int skip = 0; @@ -1169,7 +1169,7 @@ static void outliner_sort(ListBase *lb) static void outliner_collections_children_sort(ListBase *lb) { - TreeElement *last_te = reinterpret_cast<TreeElement *>(lb->last); + TreeElement *last_te = static_cast<TreeElement *>(lb->last); if (last_te == nullptr) { return; } @@ -1180,7 +1180,7 @@ static void outliner_collections_children_sort(ListBase *lb) int totelem = BLI_listbase_count(lb); if (totelem > 1) { - tTreeSort *tear = reinterpret_cast<tTreeSort *>( + tTreeSort *tear = static_cast<tTreeSort *>( MEM_mallocN(totelem * sizeof(tTreeSort), "tree sort array")); tTreeSort *tp = tear; @@ -1551,8 +1551,7 @@ static TreeElement *outliner_extract_children_from_subtree(TreeElement *element, if (outliner_element_is_collection_or_object(element)) { TreeElement *te_prev = nullptr; - for (TreeElement *te = reinterpret_cast<TreeElement *>(element->subtree.last); te; - te = te_prev) { + for (TreeElement *te = static_cast<TreeElement *>(element->subtree.last); te; te = te_prev) { te_prev = te->prev; if (!outliner_element_is_collection_or_object(te)) { @@ -1579,7 +1578,7 @@ static int outliner_filter_subtree(SpaceOutliner *space_outliner, TreeElement *te, *te_next; TreeStoreElem *tselem; - for (te = reinterpret_cast<TreeElement *>(lb->first); te; te = te_next) { + for (te = static_cast<TreeElement *>(lb->first); te; te = te_next) { te_next = te->next; if ((outliner_element_visible_get(view_layer, te, exclude_filter) == false)) { /* Don't free the tree, but extract the children from the parent and add to this tree. */ diff --git a/source/blender/editors/space_outliner/outliner_utils.cc b/source/blender/editors/space_outliner/outliner_utils.cc index 0db612ce6db..d8c50cd04f9 100644 --- a/source/blender/editors/space_outliner/outliner_utils.cc +++ b/source/blender/editors/space_outliner/outliner_utils.cc @@ -98,7 +98,7 @@ static TreeElement *outliner_find_item_at_x_in_row_recursive(const TreeElement * float view_co_x, bool *r_is_merged_icon) { - TreeElement *child_te = reinterpret_cast<TreeElement *>(parent_te->subtree.first); + TreeElement *child_te = static_cast<TreeElement *>(parent_te->subtree.first); while (child_te) { const bool over_element = (view_co_x > child_te->xs) && (view_co_x < child_te->xend); @@ -282,8 +282,7 @@ bool outliner_tree_traverse(const SpaceOutliner *space_outliner, TreeTraversalFunc func, void *customdata) { - for (TreeElement *te = reinterpret_cast<TreeElement *>(tree->first), *te_next; te; - te = te_next) { + for (TreeElement *te = static_cast<TreeElement *>(tree->first), *te_next; te; te = te_next) { TreeTraversalAction func_retval = TRAVERSE_CONTINUE; /* in case te is freed in callback */ TreeStoreElem *tselem = TREESTORE(te); diff --git a/source/blender/editors/space_outliner/space_outliner.cc b/source/blender/editors/space_outliner/space_outliner.cc index 5bcd1edebc0..61bc3d35dfd 100644 --- a/source/blender/editors/space_outliner/space_outliner.cc +++ b/source/blender/editors/space_outliner/space_outliner.cc @@ -101,7 +101,7 @@ static void outliner_main_region_listener(const wmRegionListenerParams *params) ScrArea *area = params->area; ARegion *region = params->region; wmNotifier *wmn = params->notifier; - SpaceOutliner *space_outliner = reinterpret_cast<SpaceOutliner *>(area->spacedata.first); + SpaceOutliner *space_outliner = static_cast<SpaceOutliner *>(area->spacedata.first); /* context changes */ switch (wmn->category) { @@ -264,7 +264,7 @@ static void outliner_main_region_message_subscribe(const wmRegionMessageSubscrib struct wmMsgBus *mbus = params->message_bus; ScrArea *area = params->area; ARegion *region = params->region; - SpaceOutliner *space_outliner = reinterpret_cast<SpaceOutliner *>(area->spacedata.first); + SpaceOutliner *space_outliner = static_cast<SpaceOutliner *>(area->spacedata.first); wmMsgSubscribeValue msg_sub_value_region_tag_redraw{}; msg_sub_value_region_tag_redraw.owner = region; @@ -361,7 +361,7 @@ static void outliner_free(SpaceLink *sl) /* spacetype; init callback */ static void outliner_init(wmWindowManager *UNUSED(wm), ScrArea *area) { - SpaceOutliner *space_outliner = reinterpret_cast<SpaceOutliner *>(area->spacedata.first); + SpaceOutliner *space_outliner = static_cast<SpaceOutliner *>(area->spacedata.first); if (space_outliner->runtime == nullptr) { space_outliner->runtime = MEM_new<SpaceOutliner_Runtime>("SpaceOutliner_Runtime"); @@ -437,7 +437,7 @@ static void outliner_id_remap(ScrArea *area, SpaceLink *slink, const struct IDRe static void outliner_deactivate(struct ScrArea *area) { /* Remove hover highlights */ - SpaceOutliner *space_outliner = reinterpret_cast<SpaceOutliner *>(area->spacedata.first); + SpaceOutliner *space_outliner = static_cast<SpaceOutliner *>(area->spacedata.first); outliner_flag_set(*space_outliner, TSE_HIGHLIGHTED_ANY, false); ED_region_tag_redraw_no_rebuild(BKE_area_find_region_type(area, RGN_TYPE_WINDOW)); } diff --git a/source/blender/editors/space_outliner/tree/common.cc b/source/blender/editors/space_outliner/tree/common.cc index 349d36e2fe6..e590b0c97d1 100644 --- a/source/blender/editors/space_outliner/tree/common.cc +++ b/source/blender/editors/space_outliner/tree/common.cc @@ -38,7 +38,7 @@ void outliner_make_object_parent_hierarchy(ListBase *lb) { /* build hierarchy */ /* XXX also, set extents here... */ - TreeElement *te = reinterpret_cast<TreeElement *>(lb->first); + TreeElement *te = static_cast<TreeElement *>(lb->first); while (te) { TreeElement *ten = te->next; TreeStoreElem *tselem = TREESTORE(te); diff --git a/source/blender/editors/space_outliner/tree/tree_element.cc b/source/blender/editors/space_outliner/tree/tree_element.cc index a401662297a..4a540c3ce87 100644 --- a/source/blender/editors/space_outliner/tree/tree_element.cc +++ b/source/blender/editors/space_outliner/tree/tree_element.cc @@ -4,6 +4,9 @@ * \ingroup spoutliner */ +#include <string> +#include <string_view> + #include "DNA_anim_types.h" #include "DNA_listBase.h" #include "DNA_space_types.h" @@ -57,7 +60,7 @@ std::unique_ptr<AbstractTreeElement> AbstractTreeElement::createFromType(const i return std::make_unique<TreeElementLabel>(legacy_te, static_cast<const char *>(idv)); case TSE_ANIM_DATA: return std::make_unique<TreeElementAnimData>(legacy_te, - *reinterpret_cast<IdAdtTemplate *>(idv)->adt); + *static_cast<IdAdtTemplate *>(idv)->adt); case TSE_DRIVER_BASE: return std::make_unique<TreeElementDriverBase>(legacy_te, *static_cast<AnimData *>(idv)); case TSE_NLA: @@ -83,22 +86,20 @@ std::unique_ptr<AbstractTreeElement> AbstractTreeElement::createFromType(const i return std::make_unique<TreeElementOverridesPropertyOperation>( legacy_te, *static_cast<TreeElementOverridesData *>(idv)); case TSE_RNA_STRUCT: - return std::make_unique<TreeElementRNAStruct>(legacy_te, - *reinterpret_cast<PointerRNA *>(idv)); + return std::make_unique<TreeElementRNAStruct>(legacy_te, *static_cast<PointerRNA *>(idv)); case TSE_RNA_PROPERTY: return std::make_unique<TreeElementRNAProperty>( - legacy_te, *reinterpret_cast<PointerRNA *>(idv), legacy_te.index); + legacy_te, *static_cast<PointerRNA *>(idv), legacy_te.index); case TSE_RNA_ARRAY_ELEM: return std::make_unique<TreeElementRNAArrayElement>( - legacy_te, *reinterpret_cast<PointerRNA *>(idv), legacy_te.index); + legacy_te, *static_cast<PointerRNA *>(idv), legacy_te.index); case TSE_SEQUENCE: - return std::make_unique<TreeElementSequence>(legacy_te, *reinterpret_cast<Sequence *>(idv)); + return std::make_unique<TreeElementSequence>(legacy_te, *static_cast<Sequence *>(idv)); case TSE_SEQ_STRIP: - return std::make_unique<TreeElementSequenceStrip>(legacy_te, - *reinterpret_cast<Strip *>(idv)); + return std::make_unique<TreeElementSequenceStrip>(legacy_te, *static_cast<Strip *>(idv)); case TSE_SEQUENCE_DUP: - return std::make_unique<TreeElementSequenceStripDuplicate>( - legacy_te, *reinterpret_cast<Sequence *>(idv)); + return std::make_unique<TreeElementSequenceStripDuplicate>(legacy_te, + *static_cast<Sequence *>(idv)); default: break; } @@ -116,6 +117,17 @@ std::optional<BIFIconID> AbstractTreeElement::getIcon() const return {}; } +void AbstractTreeElement::print_path() +{ + std::string path = legacy_te_.name; + + for (TreeElement *parent = legacy_te_.parent; parent; parent = parent->parent) { + path = parent->name + std::string_view("/") + path; + } + + std::cout << path << std::endl; +} + void AbstractTreeElement::uncollapse_by_default(TreeElement *legacy_te) { if (!TREESTORE(legacy_te)->used) { diff --git a/source/blender/editors/space_outliner/tree/tree_element.hh b/source/blender/editors/space_outliner/tree/tree_element.hh index a3598e7740b..fc6211f20ea 100644 --- a/source/blender/editors/space_outliner/tree/tree_element.hh +++ b/source/blender/editors/space_outliner/tree/tree_element.hh @@ -75,6 +75,16 @@ class AbstractTreeElement { virtual std::optional<BIFIconID> getIcon() const; /** + * Debugging helper: Print effective path of this tree element, constructed out of the + * #TreeElement.name of each element. E.g.: + * - Lorem + * - ipsum dolor sit + * - amet + * will print: Lorem/ipsum dolor sit/amet. + */ + void print_path(); + + /** * Expand this tree element if it is displayed for the first time (as identified by its * tree-store element). * diff --git a/source/blender/editors/space_outliner/tree/tree_element_overrides.cc b/source/blender/editors/space_outliner/tree/tree_element_overrides.cc index 7db6b9635ee..49cabd5117f 100644 --- a/source/blender/editors/space_outliner/tree/tree_element_overrides.cc +++ b/source/blender/editors/space_outliner/tree/tree_element_overrides.cc @@ -153,7 +153,7 @@ void TreeElementOverridesBase::expand(SpaceOutliner &space_outliner) const /** \} */ /* -------------------------------------------------------------------- */ -/** \name Overriden Property +/** \name Overridden Property * * Represents an RNA property that was overridden. * @@ -187,7 +187,7 @@ StringRefNull TreeElementOverridesProperty::getWarning() const /** \} */ /* -------------------------------------------------------------------- */ -/** \name Overriden Property Operation +/** \name Overridden Property Operation * * See #TreeElementOverridesPropertyOperation. * \{ */ @@ -371,8 +371,7 @@ void OverrideRNAPathTreeBuilder::ensure_entire_collection( const char *coll_prop_path, short &index) { - AbstractTreeElement *abstract_parent = tree_element_cast<AbstractTreeElement>(&te_to_expand); - BLI_assert(abstract_parent != nullptr); + BLI_assert(tree_element_cast<AbstractTreeElement>(&te_to_expand) != nullptr); TreeElement *previous_te = nullptr; int item_idx = 0; diff --git a/source/blender/editors/space_outliner/tree/tree_element_overrides.hh b/source/blender/editors/space_outliner/tree/tree_element_overrides.hh index acf35033ce1..f8ca146a4ea 100644 --- a/source/blender/editors/space_outliner/tree/tree_element_overrides.hh +++ b/source/blender/editors/space_outliner/tree/tree_element_overrides.hh @@ -66,7 +66,7 @@ class TreeElementOverridesProperty : public AbstractTreeElement { }; /** - * Represent a single operation within an overriden property. While usually a single override + * Represent a single operation within an overridden property. While usually a single override * property represents a single operation (changing the value), a single overridden collection * property may have multiple operations, e.g. to insert or remove collection items. * diff --git a/source/blender/editors/space_outliner/tree/tree_element_rna.cc b/source/blender/editors/space_outliner/tree/tree_element_rna.cc index 914104f1f06..6dd5ec84041 100644 --- a/source/blender/editors/space_outliner/tree/tree_element_rna.cc +++ b/source/blender/editors/space_outliner/tree/tree_element_rna.cc @@ -117,7 +117,7 @@ void TreeElementRNAStruct::expand(SpaceOutliner &space_outliner) const for (int index = 0; index < tot; index++) { PointerRNA propptr; RNA_property_collection_lookup_int(&ptr, iterprop, index, &propptr); - if (!(RNA_property_flag(reinterpret_cast<PropertyRNA *>(propptr.data)) & PROP_HIDDEN)) { + if (!(RNA_property_flag(static_cast<PropertyRNA *>(propptr.data)) & PROP_HIDDEN)) { outliner_add_element( &space_outliner, &legacy_te_.subtree, &ptr, &legacy_te_, TSE_RNA_PROPERTY, index); } @@ -146,7 +146,7 @@ TreeElementRNAProperty::TreeElementRNAProperty(TreeElement &legacy_te, PropertyRNA *iterprop = RNA_struct_iterator_property(rna_ptr.type); RNA_property_collection_lookup_int(&rna_ptr, iterprop, index, &propptr); - PropertyRNA *prop = reinterpret_cast<PropertyRNA *>(propptr.data); + PropertyRNA *prop = static_cast<PropertyRNA *>(propptr.data); legacy_te_.name = RNA_property_ui_name(prop); rna_prop_ = prop; @@ -232,8 +232,7 @@ TreeElementRNAArrayElement::TreeElementRNAArrayElement(TreeElement &legacy_te, char c = RNA_property_array_item_char(TreeElementRNAArrayElement::getPropertyRNA(), index); - legacy_te_.name = reinterpret_cast<char *>( - MEM_callocN(sizeof(char[20]), "OutlinerRNAArrayName")); + legacy_te_.name = static_cast<char *>(MEM_callocN(sizeof(char[20]), "OutlinerRNAArrayName")); if (c) { sprintf((char *)legacy_te_.name, " %c", c); } diff --git a/source/blender/editors/space_script/script_edit.c b/source/blender/editors/space_script/script_edit.c index e8c7590c1fe..a32c8a3f85a 100644 --- a/source/blender/editors/space_script/script_edit.c +++ b/source/blender/editors/space_script/script_edit.c @@ -100,7 +100,7 @@ static int script_reload_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - /* TODO(campbell): this crashes on netrender and keying sets, need to look into why + /* TODO(@campbellbarton): this crashes on netrender and keying sets, need to look into why * disable for now unless running in debug mode. */ /* It would be nice if we could detect when this is called from the Python diff --git a/source/blender/editors/space_sequencer/sequencer_drag_drop.c b/source/blender/editors/space_sequencer/sequencer_drag_drop.c index f6561cf07b9..4796d80b3a0 100644 --- a/source/blender/editors/space_sequencer/sequencer_drag_drop.c +++ b/source/blender/editors/space_sequencer/sequencer_drag_drop.c @@ -51,7 +51,9 @@ typedef struct SeqDropCoords { float start_frame, channel; int strip_len, channel_len; + float playback_rate; bool in_use; + bool has_read_mouse_pos; bool is_intersecting; bool use_snapping; float snap_point_x; @@ -63,7 +65,7 @@ typedef struct SeqDropCoords { * preloading data on drag start. * Therefore we will for now use a global variable for this. */ -static SeqDropCoords g_drop_coords = {.in_use = false}; +static SeqDropCoords g_drop_coords = {.in_use = false, .has_read_mouse_pos = false}; static void generic_poll_operations(const wmEvent *event, uint8_t type) { @@ -82,31 +84,134 @@ static bool image_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *ev } } - return WM_drag_is_ID_type(drag, ID_IM); + if (WM_drag_is_ID_type(drag, ID_IM)) { + generic_poll_operations(event, TH_SEQ_IMAGE); + return true; + } + + return false; } -static bool movie_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *event) +static bool is_movie(wmDrag *drag) { if (drag->type == WM_DRAG_PATH) { - if (ELEM(drag->icon, 0, ICON_FILE_MOVIE, ICON_FILE_BLANK)) { /* Rule might not work? */ - generic_poll_operations(event, TH_SEQ_MOVIE); + if (ELEM(drag->icon, ICON_FILE_MOVIE, ICON_FILE_BLANK)) { /* Rule might not work? */ return true; } } + if (WM_drag_is_ID_type(drag, ID_MC)) { + return true; + } + return false; +} + +static bool movie_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *event) +{ + if (is_movie(drag)) { + generic_poll_operations(event, TH_SEQ_MOVIE); + return true; + } - return WM_drag_is_ID_type(drag, ID_MC); + return false; } -static bool sound_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *event) +static bool is_sound(wmDrag *drag) { if (drag->type == WM_DRAG_PATH) { if (ELEM(drag->icon, ICON_FILE_SOUND, ICON_FILE_BLANK)) { /* Rule might not work? */ - generic_poll_operations(event, TH_SEQ_AUDIO); return true; } } + if (WM_drag_is_ID_type(drag, ID_SO)) { + return true; + } + return false; +} - return WM_drag_is_ID_type(drag, ID_SO); +static bool sound_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *event) +{ + if (is_sound(drag)) { + generic_poll_operations(event, TH_SEQ_AUDIO); + return true; + } + + return false; +} + +static float update_overlay_strip_position_data(bContext *C, const int mval[2]) +{ + SeqDropCoords *coords = &g_drop_coords; + ARegion *region = CTX_wm_region(C); + Scene *scene = CTX_data_scene(C); + int hand; + View2D *v2d = ®ion->v2d; + + /* Update the position were we would place the strip if we complete the drag and drop action. + */ + UI_view2d_region_to_view(v2d, mval[0], mval[1], &coords->start_frame, &coords->channel); + coords->start_frame = roundf(coords->start_frame); + if (coords->channel < 1.0f) { + coords->channel = 1; + } + + float start_frame = coords->start_frame; + float end_frame; + float strip_len; + + if (coords->playback_rate != 0.0f) { + float scene_playback_rate = (float)scene->r.frs_sec / scene->r.frs_sec_base; + strip_len = coords->strip_len / (coords->playback_rate / scene_playback_rate); + } + else { + strip_len = coords->strip_len; + } + + end_frame = coords->start_frame + strip_len; + + if (coords->use_snapping) { + /* Do snapping via the existing transform code. */ + int snap_delta; + float snap_frame; + bool valid_snap; + + valid_snap = ED_transform_snap_sequencer_to_closest_strip_calc( + scene, region, start_frame, end_frame, &snap_delta, &snap_frame); + + if (valid_snap) { + /* We snapped onto something! */ + start_frame += snap_delta; + coords->start_frame = start_frame; + end_frame = start_frame + strip_len; + coords->snap_point_x = snap_frame; + } + else { + /* Nothing was snapped to, disable snap drawing. */ + coords->use_snapping = false; + } + } + + if (strip_len < 1) { + /* Only check if there is a strip already under the mouse cursor. */ + coords->is_intersecting = find_nearest_seq(scene, ®ion->v2d, &hand, mval); + } + else { + /* Check if there is a strip that would intersect with the new strip(s). */ + coords->is_intersecting = false; + Sequence dummy_seq = {.machine = coords->channel, + .start = coords->start_frame, + .len = coords->strip_len, + .speed_factor = 1.0f, + .media_playback_rate = coords->playback_rate, + .flag = SEQ_AUTO_PLAYBACK_RATE}; + Editing *ed = SEQ_editing_ensure(scene); + + for (int i = 0; i < coords->channel_len && !coords->is_intersecting; i++) { + coords->is_intersecting = SEQ_transform_test_overlap(scene, ed->seqbasep, &dummy_seq); + dummy_seq.machine++; + } + } + + return strip_len; } static void sequencer_drop_copy(bContext *C, wmDrag *drag, wmDropBox *drop) @@ -153,93 +258,77 @@ static void sequencer_drop_copy(bContext *C, wmDrag *drag, wmDropBox *drop) RNA_collection_add(drop->ptr, "files", &itemptr); RNA_string_set(&itemptr, "name", file); } - - if (g_drop_coords.in_use) { - RNA_int_set(drop->ptr, "frame_start", g_drop_coords.start_frame); - RNA_int_set(drop->ptr, "channel", g_drop_coords.channel); - RNA_boolean_set(drop->ptr, "overlap_shuffle_override", true); - } - else { - Scene *scene = CTX_data_scene(C); - Editing *ed = SEQ_editing_get(scene); - ListBase *seqbase = SEQ_active_seqbase_get(ed); - ListBase *channels = SEQ_channels_displayed_get(ed); - SpaceSeq *sseq = CTX_wm_space_seq(C); - - SeqCollection *strips = SEQ_query_rendered_strips( - scene, channels, seqbase, scene->r.cfra, sseq->chanshown); - - /* Get the top most strip channel that is in view.*/ - Sequence *seq; - int max_channel = -1; - SEQ_ITERATOR_FOREACH (seq, strips) { - max_channel = max_ii(seq->machine, max_channel); - } - - if (max_channel != -1) { - RNA_int_set(drop->ptr, "channel", max_channel); - } - SEQ_collection_free(strips); - } } -} -static void update_overlay_strip_poistion_data(bContext *C, const int mval[2]) -{ - SeqDropCoords *coords = &g_drop_coords; - ARegion *region = CTX_wm_region(C); - Scene *scene = CTX_data_scene(C); - int hand; - View2D *v2d = ®ion->v2d; + if (g_drop_coords.in_use) { + if (!g_drop_coords.has_read_mouse_pos) { + /* We didn't read the mouse position, so we need to do it manually here. */ + int xy[2]; + wmWindow *win = CTX_wm_window(C); + xy[0] = win->eventstate->xy[0]; + xy[1] = win->eventstate->xy[1]; + + ARegion *region = CTX_wm_region(C); + int mval[2]; + /* Convert mouse coordinates to region local coordinates. */ + mval[0] = xy[0] - region->winrct.xmin; + mval[1] = xy[1] - region->winrct.ymin; + + update_overlay_strip_position_data(C, mval); + } - /* Update the position were we would place the strip if we complete the drag and drop action. - */ - UI_view2d_region_to_view(v2d, mval[0], mval[1], &coords->start_frame, &coords->channel); - coords->start_frame = roundf(coords->start_frame); - if (coords->channel < 1.0f) { - coords->channel = 1; + RNA_int_set(drop->ptr, "frame_start", g_drop_coords.start_frame); + RNA_int_set(drop->ptr, "channel", g_drop_coords.channel); + RNA_boolean_set(drop->ptr, "overlap_shuffle_override", true); } + else { + /* We are dropped inside the preview region. Put the strip on top of the + * current displayed frame. */ + Scene *scene = CTX_data_scene(C); + Editing *ed = SEQ_editing_get(scene); + ListBase *seqbase = SEQ_active_seqbase_get(ed); + ListBase *channels = SEQ_channels_displayed_get(ed); + SpaceSeq *sseq = CTX_wm_space_seq(C); - float start_frame = coords->start_frame; - float end_frame = coords->start_frame + coords->strip_len; - - if (coords->use_snapping) { - /* Do snapping via the existing transform code. */ - int snap_delta; - float snap_frame; - bool valid_snap; - - valid_snap = ED_transform_snap_sequencer_to_closest_strip_calc( - scene, region, start_frame, end_frame, &snap_delta, &snap_frame); + SeqCollection *strips = SEQ_query_rendered_strips( + scene, channels, seqbase, scene->r.cfra, sseq->chanshown); - if (valid_snap) { - /* We snapped onto something! */ - start_frame += snap_delta; - coords->start_frame = start_frame; - end_frame = start_frame + coords->strip_len; - coords->snap_point_x = snap_frame; + /* Get the top most strip channel that is in view.*/ + Sequence *seq; + int max_channel = -1; + SEQ_ITERATOR_FOREACH (seq, strips) { + max_channel = max_ii(seq->machine, max_channel); } - else { - /* Nothing was snapped to, disable snap drawing. */ - coords->use_snapping = false; + + if (max_channel != -1) { + RNA_int_set(drop->ptr, "channel", max_channel); } + SEQ_collection_free(strips); } +} - if (coords->strip_len < 1) { - /* Only check if there is a strip already under the mouse cursor. */ - coords->is_intersecting = find_nearest_seq(scene, ®ion->v2d, &hand, mval); +static void get_drag_path(wmDrag *drag, char r_path[FILE_MAX]) +{ + ID *id = WM_drag_get_local_ID_or_import_from_asset(drag, 0); + /* ID dropped. */ + if (id != NULL) { + const ID_Type id_type = GS(id->name); + if (id_type == ID_IM) { + Image *ima = (Image *)id; + BLI_strncpy(r_path, ima->filepath, FILE_MAX); + } + else if (id_type == ID_MC) { + MovieClip *clip = (MovieClip *)id; + BLI_strncpy(r_path, clip->filepath, FILE_MAX); + } + else if (id_type == ID_SO) { + bSound *sound = (bSound *)id; + BLI_strncpy(r_path, sound->filepath, FILE_MAX); + } + BLI_path_abs(r_path, BKE_main_blendfile_path_from_global()); } else { - /* Check if there is a strip that would intersect with the new strip(s). */ - coords->is_intersecting = false; - Sequence dummy_seq = { - .machine = coords->channel, .start = coords->start_frame, .len = coords->strip_len}; - Editing *ed = SEQ_editing_ensure(scene); - - for (int i = 0; i < coords->channel_len && !coords->is_intersecting; i++) { - coords->is_intersecting = SEQ_transform_test_overlap(scene, ed->seqbasep, &dummy_seq); - dummy_seq.machine++; - } + BLI_strncpy(r_path, drag->path, FILE_MAX); } } @@ -256,7 +345,7 @@ static void draw_seq_in_view(bContext *C, wmWindow *UNUSED(win), wmDrag *drag, c mval[0] = xy[0] - region->winrct.xmin; mval[1] = xy[1] - region->winrct.ymin; - update_overlay_strip_poistion_data(C, mval); + float strip_len = update_overlay_strip_position_data(C, mval); GPU_matrix_push(); UI_view2d_view_ortho(®ion->v2d); @@ -280,7 +369,7 @@ static void draw_seq_in_view(bContext *C, wmWindow *UNUSED(win), wmDrag *drag, c /* Draw strips. The code here is taken from sequencer_draw. */ float x1 = coords->start_frame; - float x2 = coords->start_frame + coords->strip_len; + float x2 = coords->start_frame + floorf(strip_len); float strip_color[3]; uchar text_color[4] = {255, 255, 255, 255}; float pixelx = BLI_rctf_size_x(®ion->v2d.cur) / BLI_rcti_size_x(®ion->v2d.mask); @@ -354,21 +443,22 @@ static void draw_seq_in_view(bContext *C, wmWindow *UNUSED(win), wmDrag *drag, c const char *text_array[5]; char text_display[FILE_MAX]; char filename[FILE_MAX]; - char rel_path[FILE_MAX]; + char path[FILE_MAX]; char strip_duration_text[16]; int len_text_arr = 0; + get_drag_path(drag, path); + if (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_NAME) { - BLI_split_file_part(drag->path, filename, FILE_MAX); + BLI_split_file_part(path, filename, FILE_MAX); text_array[len_text_arr++] = filename; } if (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_SOURCE) { Main *bmain = CTX_data_main(C); - BLI_strncpy(rel_path, drag->path, FILE_MAX); - BLI_path_rel(rel_path, BKE_main_blendfile_path(bmain)); + BLI_path_rel(path, BKE_main_blendfile_path(bmain)); text_array[len_text_arr++] = text_sep; - text_array[len_text_arr++] = rel_path; + text_array[len_text_arr++] = path; } if (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_STRIP_DURATION) { @@ -442,6 +532,14 @@ static void prefetch_data_fn(void *custom_data, if (anim != NULL) { g_drop_coords.strip_len = IMB_anim_get_duration(anim, IMB_TC_NONE); + short frs_sec; + float frs_sec_base; + if (IMB_anim_get_fps(anim, &frs_sec, &frs_sec_base, true)) { + g_drop_coords.playback_rate = (float)frs_sec / frs_sec_base; + } + else { + g_drop_coords.playback_rate = 0; + } IMB_free_anim(anim); #ifdef WITH_AUDASPACE /* Try to load sound and see if the video has a sound channel. */ @@ -464,7 +562,7 @@ static void free_prefetch_data_fn(void *custom_data) MEM_freeN(job_data); } -static void start_audio_video_job(bContext *C, char *path, bool only_audio) +static void start_audio_video_job(bContext *C, wmDrag *drag, bool only_audio) { g_drop_coords.strip_len = 0; g_drop_coords.channel_len = 1; @@ -478,8 +576,8 @@ static void start_audio_video_job(bContext *C, char *path, bool only_audio) DropJobData *job_data = (DropJobData *)MEM_mallocN(sizeof(DropJobData), "SeqDragDropPreviewData"); + get_drag_path(drag, job_data->path); - BLI_strncpy(job_data->path, path, FILE_MAX); job_data->only_audio = only_audio; job_data->scene_fps = FPS; @@ -492,15 +590,15 @@ static void start_audio_video_job(bContext *C, char *path, bool only_audio) static void video_prefetch(bContext *C, wmDrag *drag) { - if (drag->type == WM_DRAG_PATH && ELEM(drag->icon, ICON_FILE_MOVIE, ICON_FILE_BLANK)) { - start_audio_video_job(C, drag->path, false); + if (is_movie(drag)) { + start_audio_video_job(C, drag, false); } } static void audio_prefetch(bContext *C, wmDrag *drag) { - if (drag->type == WM_DRAG_PATH && ELEM(drag->icon, ICON_FILE_SOUND, ICON_FILE_BLANK)) { - start_audio_video_job(C, drag->path, true); + if (is_sound(drag)) { + start_audio_video_job(C, drag, true); } } @@ -534,6 +632,7 @@ static void sequencer_drop_draw_deactivate(struct wmDropBox *drop, wmDrag *UNUSE SeqDropCoords *coords = drop->draw_data; if (coords) { coords->in_use = false; + coords->has_read_mouse_pos = false; drop->draw_data = NULL; } } diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index eb2e4ef05e5..0bacbde8240 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -519,7 +519,7 @@ static void draw_seq_waveform_overlay( MEM_freeN(waveform_data); } -/* +#if 0 static size_t *waveform_append(WaveVizData *waveform_data, vec2f pos, const float value_min, @@ -529,7 +529,7 @@ static size_t *waveform_append(WaveVizData *waveform_data, const float rms, const bool is_clipping, const bool is_line_strip) -*/ +#endif static void drawmeta_contents(Scene *scene, Sequence *seqm, diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index cb95e9a75de..9313e45a1d4 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2869,7 +2869,7 @@ static int sequencer_change_path_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "directory", directory); if (is_relative_path) { - /* TODO(campbell): shouldn't this already be relative from the filesel? + /* TODO(@campbellbarton): shouldn't this already be relative from the filesel? * (as the 'filepath' is) for now just make relative here, * but look into changing after 2.60. */ BLI_path_rel(directory, BKE_main_blendfile_path(bmain)); diff --git a/source/blender/editors/space_sequencer/sequencer_scopes.c b/source/blender/editors/space_sequencer/sequencer_scopes.c index 6ba1dcc5eb8..af0aa093e40 100644 --- a/source/blender/editors/space_sequencer/sequencer_scopes.c +++ b/source/blender/editors/space_sequencer/sequencer_scopes.c @@ -17,7 +17,7 @@ #include "sequencer_intern.h" -/* XXX(campbell): why is this function better than BLI_math version? +/* XXX(@campbellbarton): why is this function better than BLI_math version? * only difference is it does some normalize after, need to double check on this. */ static void rgb_to_yuv_normalized(const float rgb[3], float yuv[3]) { diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c index 54735a4d481..461606f63aa 100644 --- a/source/blender/editors/space_text/text_autocomplete.c +++ b/source/blender/editors/space_text/text_autocomplete.c @@ -314,7 +314,7 @@ static int doc_scroll = 0; static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *event) { - /* NOTE(campbell): this code could be refactored or rewritten. */ + /* NOTE(@campbellbarton): this code could be refactored or rewritten. */ SpaceText *st = CTX_wm_space_text(C); ScrArea *area = CTX_wm_area(C); ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW); diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index a423a842019..1a2eb20d1a9 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -960,7 +960,7 @@ static void view3d_widgets(void) WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_camera); WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_camera_view); WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_empty_image); - /* TODO(campbell): Not working well enough, disable for now. */ + /* TODO(@campbellbarton): Not working well enough, disable for now. */ #if 0 WM_gizmogrouptype_append_and_link(gzmap_type, VIEW3D_GGT_armature_spline); #endif @@ -1210,6 +1210,9 @@ static void view3d_main_region_listener(const wmRegionListenerParams *params) break; } break; + case NC_NODE: + ED_region_tag_redraw(region); + break; case NC_WORLD: switch (wmn->data) { case ND_WORLD_DRAW: diff --git a/source/blender/editors/space_view3d/view3d_gizmo_armature.c b/source/blender/editors/space_view3d/view3d_gizmo_armature.c index 3f6167d92ca..62799dd7a5c 100644 --- a/source/blender/editors/space_view3d/view3d_gizmo_armature.c +++ b/source/blender/editors/space_view3d/view3d_gizmo_armature.c @@ -37,7 +37,7 @@ * \{ */ /* - * TODO(campbell): Current conversion is a approximation (usable not correct), + * TODO(@campbellbarton): Current conversion is a approximation (usable not correct), * we'll need to take the next/previous bones into account to get the tangent directions. * First last matrices from 'BKE_pchan_bbone_spline_setup' are close but also not quite accurate * since they're not at either end-points on the curve. diff --git a/source/blender/editors/space_view3d/view3d_navigate.h b/source/blender/editors/space_view3d/view3d_navigate.h index 721476ace57..925acd90573 100644 --- a/source/blender/editors/space_view3d/view3d_navigate.h +++ b/source/blender/editors/space_view3d/view3d_navigate.h @@ -266,12 +266,12 @@ void ED_view3d_smooth_view(struct bContext *C, * or when calling #ED_view3d_smooth_view_ex. * Otherwise pass in #V3D_SmoothParams.undo_str so an undo step is pushed as needed. */ -void ED_view3d_smooth_view_undo_begin(struct bContext *C, struct ScrArea *area); +void ED_view3d_smooth_view_undo_begin(struct bContext *C, const struct ScrArea *area); /** * Run after multiple smooth-view operations have run to push undo as needed. */ void ED_view3d_smooth_view_undo_end(struct bContext *C, - struct ScrArea *area, + const struct ScrArea *area, const char *undo_str, bool undo_grouped); diff --git a/source/blender/editors/space_view3d/view3d_navigate_smoothview.c b/source/blender/editors/space_view3d/view3d_navigate_smoothview.c index 9af9c5be45a..6b150d1e771 100644 --- a/source/blender/editors/space_view3d/view3d_navigate_smoothview.c +++ b/source/blender/editors/space_view3d/view3d_navigate_smoothview.c @@ -22,13 +22,8 @@ #include "view3d_intern.h" #include "view3d_navigate.h" /* own include */ -static void view3d_smoothview_apply_ex(bContext *C, - View3D *v3d, - ARegion *region, - bool sync_boxview, - bool use_autokey, - const float step, - const bool finished); +static void view3d_smoothview_apply_with_interp( + bContext *C, View3D *v3d, RegionView3D *rv3d, const bool use_autokey, const float factor); /* -------------------------------------------------------------------- */ /** \name Smooth View Undo Handling @@ -45,7 +40,7 @@ static void view3d_smoothview_apply_ex(bContext *C, * operations are executed once smooth-view has started. * \{ */ -void ED_view3d_smooth_view_undo_begin(bContext *C, ScrArea *area) +void ED_view3d_smooth_view_undo_begin(bContext *C, const ScrArea *area) { const View3D *v3d = area->spacedata.first; Object *camera = v3d->camera; @@ -58,11 +53,11 @@ void ED_view3d_smooth_view_undo_begin(bContext *C, ScrArea *area) * NOTE: It doesn't matter if the actual object being manipulated is the camera or not. */ camera->id.tag &= ~LIB_TAG_DOIT; - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + LISTBASE_FOREACH (const ARegion *, region, &area->regionbase) { if (region->regiontype != RGN_TYPE_WINDOW) { continue; } - RegionView3D *rv3d = region->regiondata; + const RegionView3D *rv3d = region->regiondata; if (ED_view3d_camera_lock_undo_test(v3d, rv3d, C)) { camera->id.tag |= LIB_TAG_DOIT; break; @@ -71,7 +66,7 @@ void ED_view3d_smooth_view_undo_begin(bContext *C, ScrArea *area) } void ED_view3d_smooth_view_undo_end(bContext *C, - ScrArea *area, + const ScrArea *area, const char *undo_str, const bool undo_grouped) { @@ -94,15 +89,15 @@ void ED_view3d_smooth_view_undo_end(bContext *C, * so even in the case there is a quad-view with multiple camera views set, these will all * reference the same camera. In this case it doesn't matter which region is used. * If in the future multiple cameras are supported, this logic can be extended. */ - ARegion *region_camera = NULL; + const ARegion *region_camera = NULL; /* An undo push should be performed. */ bool is_interactive = false; - LISTBASE_FOREACH (ARegion *, region, &area->regionbase) { + LISTBASE_FOREACH (const ARegion *, region, &area->regionbase) { if (region->regiontype != RGN_TYPE_WINDOW) { continue; } - RegionView3D *rv3d = region->regiondata; + const RegionView3D *rv3d = region->regiondata; if (ED_view3d_camera_lock_undo_test(v3d, rv3d, C)) { region_camera = region; if (rv3d->sms) { @@ -115,17 +110,13 @@ void ED_view3d_smooth_view_undo_end(bContext *C, return; } - /* Arguments to #view3d_smoothview_apply_ex to temporarily apply transformation. */ - const bool sync_boxview = false; - const bool use_autokey = false; - const bool finished = false; + RegionView3D *rv3d = region_camera->regiondata; /* Fast forward, undo push, then rewind. */ if (is_interactive) { - view3d_smoothview_apply_ex(C, v3d, region_camera, sync_boxview, use_autokey, 1.0f, finished); + view3d_smoothview_apply_with_interp(C, v3d, rv3d, false, 1.0f); } - RegionView3D *rv3d = region_camera->regiondata; if (undo_grouped) { ED_view3d_camera_lock_undo_grouped_push(undo_str, v3d, rv3d, C); } @@ -134,7 +125,7 @@ void ED_view3d_smooth_view_undo_end(bContext *C, } if (is_interactive) { - view3d_smoothview_apply_ex(C, v3d, region_camera, sync_boxview, use_autokey, 0.0f, finished); + view3d_smoothview_apply_with_interp(C, v3d, rv3d, false, 0.0f); } } @@ -397,110 +388,112 @@ void ED_view3d_smooth_view(bContext *C, } } -static void view3d_smoothview_apply_ex(bContext *C, - View3D *v3d, - ARegion *region, - bool sync_boxview, - bool use_autokey, - const float step, - const bool finished) +/** + * Apply with interpolation, on completion run #view3d_smoothview_apply_and_finish. + */ +static void view3d_smoothview_apply_with_interp( + bContext *C, View3D *v3d, RegionView3D *rv3d, const bool use_autokey, const float factor) { - wmWindowManager *wm = CTX_wm_manager(C); - RegionView3D *rv3d = region->regiondata; struct SmoothView3DStore *sms = rv3d->sms; - /* end timer */ - if (finished) { - wmWindow *win = CTX_wm_window(C); + interp_qt_qtqt(rv3d->viewquat, sms->src.quat, sms->dst.quat, factor); - /* if we went to camera, store the original */ - if (sms->to_camera) { - rv3d->persp = RV3D_CAMOB; - view3d_smooth_view_state_restore(&sms->org, v3d, rv3d); - } - else { - const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + if (sms->use_dyn_ofs) { + view3d_orbit_apply_dyn_ofs( + rv3d->ofs, sms->src.ofs, sms->src.quat, rv3d->viewquat, sms->dyn_ofs); + } + else { + interp_v3_v3v3(rv3d->ofs, sms->src.ofs, sms->dst.ofs, factor); + } - view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d); + rv3d->dist = interpf(sms->dst.dist, sms->src.dist, factor); + v3d->lens = interpf(sms->dst.lens, sms->src.lens, factor); - ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d); + const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + if (ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d)) { + if (use_autokey) { ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true); } + } +} - if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) { - rv3d->view = sms->org_view; - } - - MEM_freeN(rv3d->sms); - rv3d->sms = NULL; +/** + * Apply the view-port transformation & free smooth-view related data. + */ +static void view3d_smoothview_apply_and_finish(bContext *C, View3D *v3d, RegionView3D *rv3d) +{ + wmWindowManager *wm = CTX_wm_manager(C); + struct SmoothView3DStore *sms = rv3d->sms; - WM_event_remove_timer(wm, win, rv3d->smooth_timer); - rv3d->smooth_timer = NULL; - rv3d->rflag &= ~RV3D_NAVIGATING; + wmWindow *win = CTX_wm_window(C); - /* Event handling won't know if a UI item has been moved under the pointer. */ - WM_event_add_mousemove(win); + /* if we went to camera, store the original */ + if (sms->to_camera) { + rv3d->persp = RV3D_CAMOB; + view3d_smooth_view_state_restore(&sms->org, v3d, rv3d); } else { - /* ease in/out */ - const float step_inv = 1.0f - step; - - interp_qt_qtqt(rv3d->viewquat, sms->src.quat, sms->dst.quat, step); - - if (sms->use_dyn_ofs) { - view3d_orbit_apply_dyn_ofs( - rv3d->ofs, sms->src.ofs, sms->src.quat, rv3d->viewquat, sms->dyn_ofs); - } - else { - interp_v3_v3v3(rv3d->ofs, sms->src.ofs, sms->dst.ofs, step); - } + const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - rv3d->dist = sms->dst.dist * step + sms->src.dist * step_inv; - v3d->lens = sms->dst.lens * step + sms->src.lens * step_inv; + view3d_smooth_view_state_restore(&sms->dst, v3d, rv3d); - const Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); - ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d); - if (use_autokey && ED_screen_animation_playing(wm)) { + if (ED_view3d_camera_lock_sync(depsgraph, v3d, rv3d)) { ED_view3d_camera_lock_autokey(v3d, rv3d, C, true, true); } } - if (sync_boxview && (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW)) { - view3d_boxview_copy(CTX_wm_area(C), region); + if ((RV3D_LOCK_FLAGS(rv3d) & RV3D_LOCK_ROTATION) == 0) { + rv3d->view = sms->org_view; } + MEM_freeN(rv3d->sms); + rv3d->sms = NULL; + + WM_event_remove_timer(wm, win, rv3d->smooth_timer); + rv3d->smooth_timer = NULL; + rv3d->rflag &= ~RV3D_NAVIGATING; + + /* Event handling won't know if a UI item has been moved under the pointer. */ + WM_event_add_mousemove(win); + /* NOTE: this doesn't work right because the v3d->lens is now used in ortho mode r51636, * when switching camera in quad-view the other ortho views would zoom & reset. * * For now only redraw all regions when smooth-view finishes. */ - if (step >= 1.0f) { - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); - } - else { - ED_region_tag_redraw(region); - } + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); } /* only meant for timer usage */ -static void view3d_smoothview_apply(bContext *C, View3D *v3d, ARegion *region, bool sync_boxview) +static void view3d_smoothview_apply_from_timer(bContext *C, View3D *v3d, ARegion *region) { + wmWindowManager *wm = CTX_wm_manager(C); RegionView3D *rv3d = region->regiondata; struct SmoothView3DStore *sms = rv3d->sms; - float step; + float factor; if (sms->time_allowed != 0.0) { - step = (float)((rv3d->smooth_timer->duration) / sms->time_allowed); + factor = (float)((rv3d->smooth_timer->duration) / sms->time_allowed); } else { - step = 1.0f; + factor = 1.0f; + } + if (factor >= 1.0f) { + view3d_smoothview_apply_and_finish(C, v3d, rv3d); } - const bool finished = step >= 1.0f; - if (!finished) { - step = (3.0f * step * step - 2.0f * step * step * step); + else { + /* Ease in/out smoothing. */ + factor = (3.0f * factor * factor - 2.0f * factor * factor * factor); + const bool use_autokey = ED_screen_animation_playing(wm); + view3d_smoothview_apply_with_interp(C, v3d, rv3d, use_autokey, factor); } - view3d_smoothview_apply_ex(C, v3d, region, sync_boxview, true, step, finished); + + if (RV3D_LOCK_FLAGS(rv3d) & RV3D_BOXVIEW) { + view3d_boxview_copy(CTX_wm_area(C), region); + } + + ED_region_tag_redraw(region); } static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) @@ -514,7 +507,7 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const w return OPERATOR_PASS_THROUGH; } - view3d_smoothview_apply(C, v3d, region, true); + view3d_smoothview_apply_from_timer(C, v3d, region); return OPERATOR_FINISHED; } @@ -522,12 +515,10 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *UNUSED(op), const w void ED_view3d_smooth_view_force_finish(bContext *C, View3D *v3d, ARegion *region) { RegionView3D *rv3d = region->regiondata; - if (rv3d && rv3d->sms) { - rv3d->sms->time_allowed = 0.0; /* force finishing */ - view3d_smoothview_apply(C, v3d, region, false); + view3d_smoothview_apply_and_finish(C, v3d, rv3d); - /* force update of view matrix so tools that run immediately after + /* Force update of view matrix so tools that run immediately after * can use them without redrawing first */ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); Scene *scene = CTX_data_scene(C); diff --git a/source/blender/editors/space_view3d/view3d_utils.c b/source/blender/editors/space_view3d/view3d_utils.c index 0d88824a784..5f2a4e8c4cc 100644 --- a/source/blender/editors/space_view3d/view3d_utils.c +++ b/source/blender/editors/space_view3d/view3d_utils.c @@ -708,8 +708,11 @@ bool ED_view3d_camera_lock_undo_test(const View3D *v3d, * unnecessary undo steps so undo push for them is not supported for now. Also operators that uses * smooth view for navigation are excluded too, but they can be supported, see: D15345. */ -static bool view3d_camera_lock_undo_ex( - const char *str, View3D *v3d, RegionView3D *rv3d, struct bContext *C, bool undo_group) +static bool view3d_camera_lock_undo_ex(const char *str, + const View3D *v3d, + const RegionView3D *rv3d, + struct bContext *C, + const bool undo_group) { if (ED_view3d_camera_lock_undo_test(v3d, rv3d, C)) { if (undo_group) { @@ -723,14 +726,17 @@ static bool view3d_camera_lock_undo_ex( return false; } -bool ED_view3d_camera_lock_undo_push(const char *str, View3D *v3d, RegionView3D *rv3d, bContext *C) +bool ED_view3d_camera_lock_undo_push(const char *str, + const View3D *v3d, + const RegionView3D *rv3d, + bContext *C) { return view3d_camera_lock_undo_ex(str, v3d, rv3d, C, false); } bool ED_view3d_camera_lock_undo_grouped_push(const char *str, - View3D *v3d, - RegionView3D *rv3d, + const View3D *v3d, + const RegionView3D *rv3d, bContext *C) { return view3d_camera_lock_undo_ex(str, v3d, rv3d, C, true); diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c index b5a85f57b84..f67a44703e5 100644 --- a/source/blender/editors/transform/transform_convert_mesh.c +++ b/source/blender/editors/transform/transform_convert_mesh.c @@ -1314,7 +1314,8 @@ void transform_convert_mesh_crazyspace_detect(TransInfo *t, * correction with \a quats, relative to the coordinates after * the modifiers that support deform matrices \a defcos. */ -#if 0 /* TODO(campbell): fix crazy-space & extrude so it can be enabled for general use. */ +#if 0 /* TODO(@campbellbarton): fix crazy-space & extrude so it can be enabled for general use. \ + */ if ((totleft > 0) || (totleft == -1)) #else if (totleft > 0) @@ -2123,7 +2124,7 @@ void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t) FOREACH_TRANS_DATA_CONTAINER (t, tc) { /* table needs to be created for each edit command, since vertices can move etc */ ED_mesh_mirror_spatial_table_end(tc->obedit); - /* TODO(campbell): xform: We need support for many mirror objects at once! */ + /* TODO(@campbellbarton): xform: We need support for many mirror objects at once! */ break; } } diff --git a/source/blender/editors/transform/transform_gizmo_extrude_3d.c b/source/blender/editors/transform/transform_gizmo_extrude_3d.c index 131a7fd517f..a3b5fd2c575 100644 --- a/source/blender/editors/transform/transform_gizmo_extrude_3d.c +++ b/source/blender/editors/transform/transform_gizmo_extrude_3d.c @@ -261,7 +261,7 @@ static void gizmo_mesh_extrude_refresh(const bContext *C, wmGizmoGroup *gzgroup) copy_m3_m3(ggd->data.normal_mat3, tbounds_normal.axis); } - /* TODO(campbell): run second since this modifies the 3D view, it should not. */ + /* TODO(@campbellbarton): run second since this modifies the 3D view, it should not. */ if (!ED_transform_calc_gizmo_stats(C, &(struct TransformCalcParams){ .orientation_index = ggd->data.orientation_index + 1, diff --git a/source/blender/editors/transform/transform_mode_bend.c b/source/blender/editors/transform/transform_mode_bend.c index acc6b20810f..a48f84ef0bc 100644 --- a/source/blender/editors/transform/transform_mode_bend.c +++ b/source/blender/editors/transform/transform_mode_bend.c @@ -262,7 +262,7 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2])) +values.scale * shell_angle_to_dist((float)M_PI_2 + values.angle)); } - /* TODO(campbell): xform, compensate object center. */ + /* TODO(@campbellbarton): xform, compensate object center. */ FOREACH_TRANS_DATA_CONTAINER (t, tc) { float warp_sta_local[3]; diff --git a/source/blender/editors/transform/transform_mode_edge_slide.c b/source/blender/editors/transform/transform_mode_edge_slide.c index a3c49d2362f..b48ba0640ad 100644 --- a/source/blender/editors/transform/transform_mode_edge_slide.c +++ b/source/blender/editors/transform/transform_mode_edge_slide.c @@ -1204,7 +1204,7 @@ void drawEdgeSlide(TransInfo *t) immUniformThemeColorShadeAlpha(TH_EDGE_SELECT, 80, alpha_shade); immBegin(GPU_PRIM_LINES, sld->totsv * 2); - /* TODO(campbell): Loop over all verts. */ + /* TODO(@campbellbarton): Loop over all verts. */ sv = sld->sv; for (i = 0; i < sld->totsv; i++, sv++) { float a[3], b[3]; diff --git a/source/blender/editors/transform/transform_mode_resize.c b/source/blender/editors/transform/transform_mode_resize.c index 1ccda96fecb..70599c3577c 100644 --- a/source/blender/editors/transform/transform_mode_resize.c +++ b/source/blender/editors/transform/transform_mode_resize.c @@ -126,19 +126,14 @@ static void constrain_scale_to_boundary(const float numerator, static bool clip_uv_transform_resize(TransInfo *t, float vec[2]) { - /* Check if the current image in UV editor is a tiled image or not. */ - const SpaceImage *sima = t->area->spacedata.first; - const Image *image = sima->image; - const bool is_tiled_image = image && (image->source == IMA_SRC_TILED); /* Stores the coordinates of the closest UDIM tile. * Also acts as an offset to the tile from the origin of UV space. */ float base_offset[2] = {0.0f, 0.0f}; /* If tiled image then constrain to correct/closest UDIM tile, else 0-1 UV space. */ - if (is_tiled_image) { - BKE_image_find_nearest_tile_with_offset(image, t->center_global, base_offset); - } + const SpaceImage *sima = t->area->spacedata.first; + BKE_image_find_nearest_tile_with_offset(sima->image, t->center_global, base_offset); /* Assume no change is required. */ float scale = 1.0f; diff --git a/source/blender/editors/transform/transform_mode_translate.c b/source/blender/editors/transform/transform_mode_translate.c index 04a41814b53..8f6ec7bd98f 100644 --- a/source/blender/editors/transform/transform_mode_translate.c +++ b/source/blender/editors/transform/transform_mode_translate.c @@ -437,19 +437,13 @@ static void applyTranslationValue(TransInfo *t, const float vec[3]) static bool clip_uv_transform_translation(TransInfo *t, float vec[2]) { - /* Check if the current image in UV editor is a tiled image or not. */ - const SpaceImage *sima = t->area->spacedata.first; - const Image *image = sima->image; - const bool is_tiled_image = image && (image->source == IMA_SRC_TILED); - /* Stores the coordinates of the closest UDIM tile. * Also acts as an offset to the tile from the origin of UV space. */ float base_offset[2] = {0.0f, 0.0f}; /* If tiled image then constrain to correct/closest UDIM tile, else 0-1 UV space. */ - if (is_tiled_image) { - BKE_image_find_nearest_tile_with_offset(image, t->center_global, base_offset); - } + const SpaceImage *sima = t->area->spacedata.first; + BKE_image_find_nearest_tile_with_offset(sima->image, t->center_global, base_offset); float min[2], max[2]; min[0] = min[1] = FLT_MAX; diff --git a/source/blender/editors/transform/transform_snap_object.cc b/source/blender/editors/transform/transform_snap_object.cc index 479214ee2d3..6808f06bdd3 100644 --- a/source/blender/editors/transform/transform_snap_object.cc +++ b/source/blender/editors/transform/transform_snap_object.cc @@ -498,7 +498,8 @@ static bool snap_object_is_snappable(const SnapObjectContext *sctx, const bool is_edited = (base->object->mode == OB_MODE_EDIT); const bool is_selectable = (base->flag & BASE_SELECTABLE); /* Get attributes of state. */ - const bool is_in_object_mode = (base_act == NULL) || (base_act->object->mode == OB_MODE_OBJECT); + const bool is_in_object_mode = (base_act == nullptr) || + (base_act->object->mode == OB_MODE_OBJECT); if (is_in_object_mode) { /* Handle target selection options that make sense for object mode. */ diff --git a/source/blender/editors/undo/CMakeLists.txt b/source/blender/editors/undo/CMakeLists.txt index 284b725cdf0..271d05e9c04 100644 --- a/source/blender/editors/undo/CMakeLists.txt +++ b/source/blender/editors/undo/CMakeLists.txt @@ -11,6 +11,7 @@ set(INC ../../windowmanager ../../../../intern/clog ../../../../intern/guardedalloc + ../../bmesh ) set(SRC diff --git a/source/blender/editors/undo/ed_undo.c b/source/blender/editors/undo/ed_undo.c index ce14e6b180f..bb24bdac690 100644 --- a/source/blender/editors/undo/ed_undo.c +++ b/source/blender/editors/undo/ed_undo.c @@ -269,7 +269,7 @@ static int ed_undo_step_direction(bContext *C, enum eUndoStepDir step, ReportLis CLOG_INFO(&LOG, 1, "direction=%s", (step == STEP_UNDO) ? "STEP_UNDO" : "STEP_REDO"); - /* TODO(campbell): undo_system: use undo system */ + /* TODO(@campbellbarton): undo_system: use undo system */ /* grease pencil can be can be used in plenty of spaces, so check it first */ /* FIXME: This gpencil undo effectively only supports the one step undo/redo, undo based on name * or index is fully not implemented. diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 3cfe6bd61a4..36a881ec158 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -176,7 +176,7 @@ void ED_editors_init(bContext *C) } } else { - /* TODO(campbell): avoid operator calls. */ + /* TODO(@campbellbarton): avoid operator calls. */ if (obact == ob) { ED_object_mode_set(C, mode); } diff --git a/source/blender/editors/util/ed_util_imbuf.c b/source/blender/editors/util/ed_util_imbuf.c index fc5fb9f9c28..1ebbb0cecc3 100644 --- a/source/blender/editors/util/ed_util_imbuf.c +++ b/source/blender/editors/util/ed_util_imbuf.c @@ -431,7 +431,7 @@ void ED_imbuf_sample_draw(const bContext *C, ARegion *region, void *arg_info) immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); immUniformColor3fv(color); - /* TODO(campbell): lock to pixels. */ + /* TODO(@campbellbarton): lock to pixels. */ rctf sample_rect_fl; BLI_rctf_init_pt_radius( &sample_rect_fl, diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index 04128cf378c..434bfbc64f9 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -14,9 +14,6 @@ struct Scene; struct SpaceImage; struct wmOperatorType; -/* geometric utilities */ -void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len); - /* find nearest */ typedef struct UvNearestHit { diff --git a/source/blender/editors/uvedit/uvedit_islands.c b/source/blender/editors/uvedit/uvedit_islands.c index 9a31fd6469d..3877a9bb63b 100644 --- a/source/blender/editors/uvedit/uvedit_islands.c +++ b/source/blender/editors/uvedit/uvedit_islands.c @@ -259,9 +259,8 @@ static float uv_nearest_image_tile_distance(const Image *image, const float coords[2], float nearest_tile_co[2]) { - if (BKE_image_find_nearest_tile_with_offset(image, coords, nearest_tile_co) == -1) { - zero_v2(nearest_tile_co); - } + BKE_image_find_nearest_tile_with_offset(image, coords, nearest_tile_co); + /* Add 0.5 to get tile center coordinates. */ float nearest_tile_center_co[2] = {nearest_tile_co[0], nearest_tile_co[1]}; add_v2_fl(nearest_tile_center_co, 0.5f); @@ -309,23 +308,8 @@ static float uv_nearest_grid_tile_distance(const int udim_grid[2], /* -------------------------------------------------------------------- */ /** \name Calculate UV Islands - * - * \note Currently this is a private API/type, it could be made public. * \{ */ -struct FaceIsland { - struct FaceIsland *next, *prev; - BMFace **faces; - int faces_len; - rctf bounds_rect; - /** - * \note While this is duplicate information, - * it allows islands from multiple meshes to be stored in the same list. - */ - uint cd_loop_uv_offset; - float aspect_y; -}; - struct SharedUVLoopData { uint cd_loop_uv_offset; bool use_seams; @@ -347,14 +331,14 @@ static bool bm_loop_uv_shared_edge_check(const BMLoop *l_a, const BMLoop *l_b, v /** * Calculate islands and add them to \a island_list returning the number of items added. */ -static int bm_mesh_calc_uv_islands(const Scene *scene, - BMesh *bm, - ListBase *island_list, - const bool only_selected_faces, - const bool only_selected_uvs, - const bool use_seams, - const float aspect_y, - const uint cd_loop_uv_offset) +int bm_mesh_calc_uv_islands(const Scene *scene, + BMesh *bm, + ListBase *island_list, + const bool only_selected_faces, + const bool only_selected_uvs, + const bool use_seams, + const float aspect_y, + const uint cd_loop_uv_offset) { int island_added = 0; BM_mesh_elem_table_ensure(bm, BM_FACE); diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 74a9989f550..092f0c49d8a 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -189,15 +189,6 @@ void uvedit_live_unwrap_update(SpaceImage *sima, Scene *scene, Object *obedit) /** \name Geometric Utilities * \{ */ -void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len) -{ - int i; - for (i = 0; i < len; i++) { - uv[i][0] = uv_orig[i][0] * aspx; - uv[i][1] = uv_orig[i][1] * aspy; - } -} - bool ED_uvedit_minmax_multi( const Scene *scene, Object **objects_edit, uint objects_len, float r_min[2], float r_max[2]) { @@ -552,11 +543,11 @@ static bool uvedit_uv_straighten(Scene *scene, BMesh *bm, eUVWeldAlign tool) bool changed = false; /* Loop backwards to simplify logic. */ - int j1 = element_map->totalUVs; + int j1 = element_map->total_uvs; for (int i = element_map->totalIslands - 1; i >= 0; --i) { int j0 = element_map->islandIndices[i]; changed |= uvedit_uv_straighten_elements( - element_map->buf + j0, j1 - j0, cd_loop_uv_offset, tool); + element_map->storage + j0, j1 - j0, cd_loop_uv_offset, tool); j1 = j0; } diff --git a/source/blender/editors/uvedit/uvedit_select.c b/source/blender/editors/uvedit/uvedit_select.c index d59dcb4f4ed..749c59ea6a4 100644 --- a/source/blender/editors/uvedit/uvedit_select.c +++ b/source/blender/editors/uvedit/uvedit_select.c @@ -81,6 +81,7 @@ static void uv_select_tag_update_for_object(Depsgraph *depsgraph, typedef enum { UV_SSIM_AREA_UV = 1000, UV_SSIM_AREA_3D, + UV_SSIM_FACE, UV_SSIM_LENGTH_UV, UV_SSIM_LENGTH_3D, UV_SSIM_SIDES, @@ -1421,7 +1422,7 @@ static BMLoop *bm_select_edgeloop_single_side_next(const Scene *scene, scene, l_step, v_from_next, cd_loop_uv_offset); } -/* TODO(campbell): support this in the BMesh API, as we have for clearing other types. */ +/* TODO(@campbellbarton): support this in the BMesh API, as we have for clearing other types. */ static void bm_loop_tags_clear(BMesh *bm) { BMIter iter; @@ -4638,6 +4639,33 @@ static float get_uv_face_needle(const eUVSelectSimilar type, return result; } +static float get_uv_island_needle(const eUVSelectSimilar type, + const struct FaceIsland *island, + const float ob_m3[3][3], + const int cd_loop_uv_offset) + +{ + float result = 0.0f; + switch (type) { + case UV_SSIM_AREA_UV: + for (int i = 0; i < island->faces_len; i++) { + result += BM_face_calc_area_uv(island->faces[i], cd_loop_uv_offset); + } + break; + case UV_SSIM_AREA_3D: + for (int i = 0; i < island->faces_len; i++) { + result += BM_face_calc_area_with_mat3(island->faces[i], ob_m3); + } + break; + case UV_SSIM_FACE: + return island->faces_len; + default: + BLI_assert_unreachable(); + return false; + } + return result; +} + static int uv_select_similar_vert_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); @@ -4969,6 +4997,136 @@ static int uv_select_similar_face_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static bool uv_island_selected(const Scene *scene, struct FaceIsland *island) +{ + BLI_assert(island && island->faces_len); + return uvedit_face_select_test(scene, island->faces[0], island->cd_loop_uv_offset); +} + +static int uv_select_similar_island_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + ViewLayer *view_layer = CTX_data_view_layer(C); + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + ToolSettings *ts = CTX_data_tool_settings(C); + + const eUVSelectSimilar type = RNA_enum_get(op->ptr, "type"); + const float threshold = RNA_float_get(op->ptr, "threshold"); + const eSimilarCmp compare = RNA_enum_get(op->ptr, "compare"); + + uint objects_len = 0; + Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs( + view_layer, ((View3D *)NULL), &objects_len); + + ListBase *island_list_ptr = MEM_callocN(sizeof(*island_list_ptr) * objects_len, __func__); + int island_list_len = 0; + + const bool face_selected = !(scene->toolsettings->uv_flag & UV_SYNC_SELECTION); + + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + if (cd_loop_uv_offset == -1) { + continue; + } + + float aspect_y = 1.0f; /* Placeholder value, aspect doesn't change connectivity. */ + island_list_len += bm_mesh_calc_uv_islands(scene, + em->bm, + &island_list_ptr[ob_index], + face_selected, + false, + false, + aspect_y, + cd_loop_uv_offset); + } + + struct FaceIsland **island_array = MEM_callocN(sizeof(*island_array) * island_list_len, + __func__); + + int tree_index = 0; + KDTree_1d *tree_1d = BLI_kdtree_1d_new(island_list_len); + + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + if (cd_loop_uv_offset == -1) { + continue; + } + + float ob_m3[3][3]; + copy_m3_m4(ob_m3, obedit->obmat); + + int index; + LISTBASE_FOREACH_INDEX (struct FaceIsland *, island, &island_list_ptr[ob_index], index) { + island_array[index] = island; + if (!uv_island_selected(scene, island)) { + continue; + } + float needle = get_uv_island_needle(type, island, ob_m3, cd_loop_uv_offset); + if (tree_1d) { + BLI_kdtree_1d_insert(tree_1d, tree_index++, &needle); + } + } + } + + if (tree_1d != NULL) { + BLI_kdtree_1d_deduplicate(tree_1d); + BLI_kdtree_1d_balance(tree_1d); + } + + int tot_island_index = 0; + for (uint ob_index = 0; ob_index < objects_len; ob_index++) { + Object *obedit = objects[ob_index]; + BMEditMesh *em = BKE_editmesh_from_object(obedit); + const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV); + if (cd_loop_uv_offset == -1) { + continue; + } + float ob_m3[3][3]; + copy_m3_m4(ob_m3, obedit->obmat); + + bool changed = false; + int index; + LISTBASE_FOREACH_INDEX (struct FaceIsland *, island, &island_list_ptr[ob_index], index) { + island_array[tot_island_index++] = island; /* To deallocate later. */ + if (uv_island_selected(scene, island)) { + continue; + } + float needle = get_uv_island_needle(type, island, ob_m3, cd_loop_uv_offset); + bool select = ED_select_similar_compare_float_tree(tree_1d, needle, threshold, compare); + if (!select) { + continue; + } + bool do_history = false; + for (int j = 0; j < island->faces_len; j++) { + uvedit_face_select_set( + scene, em, island->faces[j], select, do_history, island->cd_loop_uv_offset); + } + changed = true; + } + + if (changed) { + uv_select_tag_update_for_object(depsgraph, ts, obedit); + } + } + + BLI_assert(tot_island_index == island_list_len); + for (int i = 0; i < island_list_len; i++) { + MEM_SAFE_FREE(island_array[i]->faces); + MEM_SAFE_FREE(island_array[i]); + } + + MEM_SAFE_FREE(island_array); + MEM_SAFE_FREE(island_list_ptr); + MEM_SAFE_FREE(objects); + BLI_kdtree_1d_free(tree_1d); + + return OPERATOR_FINISHED; +} + /* Select similar UV faces/edges/verts based on current selection. */ static int uv_select_similar_exec(bContext *C, wmOperator *op) { @@ -4990,7 +5148,7 @@ static int uv_select_similar_exec(bContext *C, wmOperator *op) return uv_select_similar_face_exec(C, op); } if (selectmode & UV_SELECT_ISLAND) { - // return uv_select_similar_island_exec(C, op); + return uv_select_similar_island_exec(C, op); } return uv_select_similar_vert_exec(C, op); @@ -5011,6 +5169,12 @@ static EnumPropertyItem prop_face_similar_types[] = { {UV_SSIM_MATERIAL, "MATERIAL", 0, "Material", ""}, {0}}; +static EnumPropertyItem prop_island_similar_types[] = { + {UV_SSIM_AREA_UV, "AREA", 0, "Area", ""}, + {UV_SSIM_AREA_3D, "AREA_3D", 0, "Area 3D", ""}, + {UV_SSIM_FACE, "FACE", 0, "Amount of Faces in Island", ""}, + {0}}; + static EnumPropertyItem prop_similar_compare_types[] = {{SIM_CMP_EQ, "EQUAL", 0, "Equal", ""}, {SIM_CMP_GT, "GREATER", 0, "Greater", ""}, {SIM_CMP_LT, "LESS", 0, "Less", ""}, @@ -5030,6 +5194,9 @@ static const EnumPropertyItem *uv_select_similar_type_itemf(bContext *C, if (selectmode & UV_SELECT_FACE) { return prop_face_similar_types; } + if (selectmode & UV_SELECT_ISLAND) { + return prop_island_similar_types; + } } return prop_vert_similar_types; diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 579674930a6..26ed98ba236 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -290,7 +290,7 @@ static void stitch_update_header(StitchStateContainer *ssc, bContext *C) static int getNumOfIslandUvs(UvElementMap *elementMap, int island) { if (island == elementMap->totalIslands - 1) { - return elementMap->totalUVs - elementMap->islandIndices[island]; + return elementMap->total_uvs - elementMap->islandIndices[island]; } return elementMap->islandIndices[island + 1] - elementMap->islandIndices[island]; } @@ -465,7 +465,7 @@ static void stitch_calculate_island_snapping(StitchState *state, angle_to_mat2(rotation_mat, rotation); numOfIslandUVs = getNumOfIslandUvs(state->element_map, i); - element = &state->element_map->buf[state->element_map->islandIndices[i]]; + element = &state->element_map->storage[state->element_map->islandIndices[i]]; for (j = 0; j < numOfIslandUVs; j++, element++) { /* stitchable uvs have already been processed, don't process */ if (!(element->flag & STITCH_PROCESSED)) { @@ -527,8 +527,8 @@ static void stitch_island_calculate_edge_rotation(UvEdge *edge, luv2 = CustomData_bmesh_get(&bm->ldata, element2->l->head.data, CD_MLOOPUV); if (ssc->mode == STITCH_VERT) { - index1 = uvfinal_map[element1 - state->element_map->buf]; - index2 = uvfinal_map[element2 - state->element_map->buf]; + index1 = uvfinal_map[element1 - state->element_map->storage]; + index2 = uvfinal_map[element2 - state->element_map->storage]; } else { index1 = edge->uv1; @@ -569,27 +569,17 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data) { - float edgecos = 1.0f, edgesin = 0.0f; - int index; - UvElement *element_iter; float rotation = 0, rotation_neg = 0; int rot_elem = 0, rot_elem_neg = 0; - BMLoop *l; if (element->island == ssc->static_island && !ssc->midpoints) { return; } - l = element->l; - - index = BM_elem_index_get(l->v); - - element_iter = state->element_map->vert[index]; - + UvElement *element_iter = BM_uv_element_get_head(state->element_map, element); for (; element_iter; element_iter = element_iter->next) { if (element_iter->separate && stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) { - int index_tmp1, index_tmp2; float normal[2]; /* only calculate rotation against static island uv verts */ @@ -597,14 +587,14 @@ static void stitch_island_calculate_vert_rotation(UvElement *element, continue; } - index_tmp1 = element_iter - state->element_map->buf; + int index_tmp1 = element_iter - state->element_map->storage; index_tmp1 = state->map[index_tmp1]; - index_tmp2 = element - state->element_map->buf; + int index_tmp2 = element - state->element_map->storage; index_tmp2 = state->map[index_tmp2]; negate_v2_v2(normal, state->normals + index_tmp2 * 2); - edgecos = dot_v2v2(normal, state->normals + index_tmp1 * 2); - edgesin = cross_v2v2(normal, state->normals + index_tmp1 * 2); + float edgecos = dot_v2v2(normal, state->normals + index_tmp1 * 2); + float edgesin = cross_v2v2(normal, state->normals + index_tmp1 * 2); if (edgesin > 0.0f) { rotation += acosf(max_ff(-1.0f, min_ff(1.0f, edgecos))); rot_elem++; @@ -653,9 +643,8 @@ static void state_delete(StitchState *state) if (state->edges) { MEM_freeN(state->edges); } - if (state->stitch_preview) { - stitch_preview_delete(state->stitch_preview); - } + stitch_preview_delete(state->stitch_preview); + state->stitch_preview = NULL; if (state->edge_hash) { BLI_ghash_free(state->edge_hash, NULL, NULL); } @@ -680,10 +669,7 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState * UvEdge *edges = state->edges; const int *map = state->map; UvElementMap *element_map = state->element_map; - UvElement *first_element = element_map->buf; - int i; - - for (i = 0; i < state->total_separate_edges; i++) { + for (int i = 0; i < state->total_separate_edges; i++) { UvEdge *edge = edges + i; if (edge->first) { @@ -696,7 +682,7 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState * UvElement *element2 = state->uvs[edge->uv2]; /* Now iterate through all faces and try to find edges sharing the same vertices */ - UvElement *iter1 = element_map->vert[BM_elem_index_get(element1->l->v)]; + UvElement *iter1 = BM_uv_element_get_head(state->element_map, element1); UvEdge *last_set = edge; int elemindex2 = BM_elem_index_get(element2->l->v); @@ -714,8 +700,8 @@ static void stitch_uv_edge_generate_linked_edges(GHash *edge_hash, StitchState * } if (iter2) { - int index1 = map[iter1 - first_element]; - int index2 = map[iter2 - first_element]; + int index1 = map[iter1 - element_map->storage]; + int index2 = map[iter2 - element_map->storage]; UvEdge edgetmp; UvEdge *edge2, *eiter; bool valid = true; @@ -764,15 +750,7 @@ static void determine_uv_stitchability(UvElement *element, StitchState *state, IslandStitchData *island_stitch_data) { - int vert_index; - UvElement *element_iter; - BMLoop *l; - - l = element->l; - - vert_index = BM_elem_index_get(l->v); - element_iter = state->element_map->vert[vert_index]; - + UvElement *element_iter = BM_uv_element_get_head(state->element_map, element); for (; element_iter; element_iter = element_iter->next) { if (element_iter->separate) { if (stitch_check_uvs_stitchable(element, element_iter, ssc, state)) { @@ -853,16 +831,7 @@ static void stitch_validate_uv_stitchability(UvElement *element, return; } - UvElement *element_iter; - int vert_index; - BMLoop *l; - - l = element->l; - - vert_index = BM_elem_index_get(l->v); - - element_iter = state->element_map->vert[vert_index]; - + UvElement *element_iter = BM_uv_element_get_head(state->element_map, element); for (; element_iter; element_iter = element_iter->next) { if (element_iter->separate) { if (element_iter == element) { @@ -1177,7 +1146,7 @@ static int stitch_process_data(StitchStateContainer *ssc, int numOfIslandUVs = 0, j; UvElement *element; numOfIslandUVs = getNumOfIslandUvs(state->element_map, i); - element = &state->element_map->buf[state->element_map->islandIndices[i]]; + element = &state->element_map->storage[state->element_map->islandIndices[i]]; for (j = 0; j < numOfIslandUVs; j++, element++) { stitch_set_face_preview_buffer_position(element->l->f, preview, preview_position); } @@ -1263,7 +1232,7 @@ static int stitch_process_data(StitchStateContainer *ssc, if (ssc->mode == STITCH_VERT) { final_position = MEM_callocN(state->selection_size * sizeof(*final_position), "stitch_uv_average"); - uvfinal_map = MEM_mallocN(state->element_map->totalUVs * sizeof(*uvfinal_map), + uvfinal_map = MEM_mallocN(state->element_map->total_uvs * sizeof(*uvfinal_map), "stitch_uv_final_map"); } else { @@ -1279,12 +1248,11 @@ static int stitch_process_data(StitchStateContainer *ssc, if (element->flag & STITCH_STITCHABLE) { BMLoop *l; MLoopUV *luv; - UvElement *element_iter; l = element->l; luv = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_MLOOPUV); - uvfinal_map[element - state->element_map->buf] = i; + uvfinal_map[element - state->element_map->storage] = i; copy_v2_v2(final_position[i].uv, luv->uv); final_position[i].count = 1; @@ -1293,8 +1261,7 @@ static int stitch_process_data(StitchStateContainer *ssc, continue; } - element_iter = state->element_map->vert[BM_elem_index_get(l->v)]; - + UvElement *element_iter = state->element_map->vertex[BM_elem_index_get(l->v)]; for (; element_iter; element_iter = element_iter->next) { if (element_iter->separate) { if (stitch_check_uvs_state_stitchable(element, element_iter, ssc, state)) { @@ -1542,6 +1509,7 @@ static int stitch_process_data_all(StitchStateContainer *ssc, Scene *scene, int static uint uv_edge_hash(const void *key) { const UvEdge *edge = key; + BLI_assert(edge->uv1 < edge->uv2); return (BLI_ghashutil_uinthash(edge->uv2) + BLI_ghashutil_uinthash(edge->uv1)); } @@ -1549,6 +1517,8 @@ static bool uv_edge_compare(const void *a, const void *b) { const UvEdge *edge1 = a; const UvEdge *edge2 = b; + BLI_assert(edge1->uv1 < edge1->uv2); + BLI_assert(edge2->uv1 < edge2->uv2); if ((edge1->uv1 == edge2->uv1) && (edge1->uv2 == edge2->uv2)) { return 0; @@ -1588,13 +1558,8 @@ static void stitch_select_edge(UvEdge *edge, StitchState *state, int always_sele /* Select all common uvs */ static void stitch_select_uv(UvElement *element, StitchState *state, int always_select) { - BMLoop *l; - UvElement *element_iter; UvElement **selection_stack = (UvElement **)state->selection_stack; - - l = element->l; - - element_iter = state->element_map->vert[BM_elem_index_get(l->v)]; + UvElement *element_iter = BM_uv_element_get_head(state->element_map, element); /* first deselect all common uvs */ for (; element_iter; element_iter = element_iter->next) { if (element_iter->separate) { @@ -1850,8 +1815,8 @@ static UvEdge *uv_edge_get(BMLoop *l, StitchState *state) UvElement *element1 = BM_uv_element_get(state->element_map, l->f, l); UvElement *element2 = BM_uv_element_get(state->element_map, l->f, l->next); - int uv1 = state->map[element1 - state->element_map->buf]; - int uv2 = state->map[element2 - state->element_map->buf]; + int uv1 = state->map[element1 - state->element_map->storage]; + int uv2 = state->map[element2 - state->element_map->storage]; if (uv1 < uv2) { tmp_edge.uv1 = uv1; @@ -1878,7 +1843,6 @@ static StitchState *stitch_init(bContext *C, int total_edges; /* maps uvelements to their first coincident uv */ int *map; - int counter = 0, i; BMFace *efa; BMLoop *l; BMIter iter, liter; @@ -1913,45 +1877,39 @@ static StitchState *stitch_init(bContext *C, ED_uvedit_get_aspect(obedit, &aspx, &aspy); state->aspect = aspx / aspy; - /* Count 'unique' uvs */ - for (i = 0; i < state->element_map->totalUVs; i++) { - if (state->element_map->buf[i].separate) { - counter++; - } - } + int unique_uvs = state->element_map->total_unique_uvs; + state->total_separate_uvs = unique_uvs; - /* explicitly set preview to NULL, - * to avoid deleting an invalid pointer on stitch_process_data */ - state->stitch_preview = NULL; /* Allocate the unique uv buffers */ - state->uvs = MEM_mallocN(sizeof(*state->uvs) * counter, "uv_stitch_unique_uvs"); + state->uvs = MEM_mallocN(sizeof(*state->uvs) * unique_uvs, "uv_stitch_unique_uvs"); /* internal uvs need no normals but it is hard and slow to keep a map of - * normals only for boundary uvs, so allocating for all uvs */ - state->normals = MEM_callocN(sizeof(*state->normals) * counter * 2, "uv_stitch_normals"); - state->total_separate_uvs = counter; - state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->totalUVs, + * normals only for boundary uvs, so allocating for all uvs. + * Times 2 because each `float[2]` is stored as `{n[2 * i], n[2*i + 1]}`. */ + state->normals = MEM_callocN(sizeof(*state->normals) * 2 * unique_uvs, "uv_stitch_normals"); + state->map = map = MEM_mallocN(sizeof(*map) * state->element_map->total_uvs, "uv_stitch_unique_map"); /* Allocate the edge stack */ edge_hash = BLI_ghash_new(uv_edge_hash, uv_edge_compare, "stitch_edge_hash"); - all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->totalUVs, "ssc_edges"); + all_edges = MEM_mallocN(sizeof(*all_edges) * state->element_map->total_uvs, "ssc_edges"); + BLI_assert(!state->stitch_preview); /* Paranoia. */ if (!state->uvs || !map || !edge_hash || !all_edges) { state_delete(state); return NULL; } - /* So that we can use this as index for the UvElements */ - counter = -1; + /* Index for the UvElements. */ + int counter = -1; /* initialize the unique UVs and map */ - for (i = 0; i < em->bm->totvert; i++) { - UvElement *element = state->element_map->vert[i]; + for (int i = 0; i < em->bm->totvert; i++) { + UvElement *element = state->element_map->vertex[i]; for (; element; element = element->next) { if (element->separate) { counter++; state->uvs[counter] = element; } /* Pointer arithmetic to the rescue, as always :). */ - map[element - state->element_map->buf] = counter; + map[element - state->element_map->storage] = counter; } } @@ -1965,13 +1923,13 @@ static StitchState *stitch_init(bContext *C, BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { UvElement *element = BM_uv_element_get(state->element_map, efa, l); - int offset1, itmp1 = element - state->element_map->buf; - int offset2, - itmp2 = BM_uv_element_get(state->element_map, efa, l->next) - state->element_map->buf; + int itmp1 = element - state->element_map->storage; + int itmp2 = BM_uv_element_get(state->element_map, efa, l->next) - + state->element_map->storage; UvEdge *edge; - offset1 = map[itmp1]; - offset2 = map[itmp2]; + int offset1 = map[itmp1]; + int offset2 = map[itmp2]; all_edges[counter].next = NULL; all_edges[counter].first = NULL; @@ -2012,7 +1970,7 @@ static StitchState *stitch_init(bContext *C, state->total_separate_edges = total_edges; /* fill the edges with data */ - i = 0; + int i = 0; GHASH_ITER (gh_iter, edge_hash) { edges[i++] = *((UvEdge *)BLI_ghashIterator_getKey(&gh_iter)); } @@ -2091,13 +2049,13 @@ static StitchState *stitch_init(bContext *C, efa = BM_face_at_index(em->bm, faceIndex); element = BM_uv_element_get( state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, elementIndex)); - uv1 = map[element - state->element_map->buf]; + uv1 = map[element - state->element_map->storage]; element = BM_uv_element_get( state->element_map, efa, BM_iter_at_index(NULL, BM_LOOPS_OF_FACE, efa, (elementIndex + 1) % efa->len)); - uv2 = map[element - state->element_map->buf]; + uv2 = map[element - state->element_map->storage]; if (uv1 < uv2) { tmp_edge.uv1 = uv1; |