diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2019-07-17 04:23:43 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2019-07-17 05:01:03 +0300 |
commit | 5ca302cb0cb40506e1f8a5f22e9baa3738ab4a58 (patch) | |
tree | 4795e4c5c4264325ef0d1e37b0b247eff065204b /source/blender | |
parent | 4a5e046c923f4858981c429dd710cdc38ac83ece (diff) |
Fix T67078: Crash with vertex slide and multi-objects
If one of the objects had invalid selected edges, it would lead to a
crash since none of the for loops were checking for whether the edge
slide data is valid.
We could refactor the macros to create a new
FOREACH_TRANS_DATA_CONTAINER_WITH_DATA
However we are too close to 2.80 final release so we manually skip them
for now.
Note: TRANS_DATA_CONTAINER_FIRST_OK cannot be used either for the same
reason.
Reviewers: campbellbarton
Differential Revision: https://developer.blender.org/D5274
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/transform/transform.c | 50 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 4 |
2 files changed, 48 insertions, 6 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 7c4f9f1d95b..1a904daafc3 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -6703,9 +6703,28 @@ static void slide_origdata_free_date(SlideOrigData *sod) /** \name Transform Edge Slide * \{ */ +/** + * Get the first valid EdgeSlideData. + * + * Note we cannot trust TRANS_DATA_CONTAINER_FIRST_OK because of multi-object that + * may leave items with invalid custom data in the transform data container. + */ +static EdgeSlideData *edgeSlideFirstGet(TransInfo *t) +{ + FOREACH_TRANS_DATA_CONTAINER (t, tc) { + EdgeSlideData *sld = tc->custom.mode.data; + if (sld == NULL) { + continue; + } + return sld; + } + BLI_assert(!"Should never happen, at least one EdgeSlideData should be valid"); + return NULL; +} + static void calcEdgeSlideCustomPoints(struct TransInfo *t) { - EdgeSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data; + EdgeSlideData *sld = edgeSlideFirstGet(t); setCustomPoints(t, &t->mouse, sld->mval_end, sld->mval_start); @@ -7679,8 +7698,12 @@ void projectEdgeSlideData(TransInfo *t, bool is_final) { FOREACH_TRANS_DATA_CONTAINER (t, tc) { EdgeSlideData *sld = tc->custom.mode.data; - SlideOrigData *sod = &sld->orig_data; + if (sld == NULL) { + continue; + } + + SlideOrigData *sod = &sld->orig_data; if (sod->use_origfaces == false) { return; } @@ -7705,7 +7728,7 @@ void freeEdgeSlideVerts(TransInfo *UNUSED(t), { EdgeSlideData *sld = custom_data->data; - if (!sld) { + if (sld == NULL) { return; } @@ -7847,9 +7870,9 @@ static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEven static void drawEdgeSlide(TransInfo *t) { - if ((t->mode == TFM_EDGE_SLIDE) && TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data) { + if ((t->mode == TFM_EDGE_SLIDE) && edgeSlideFirstGet(t)) { const EdgeSlideParams *slp = t->custom.mode.data; - EdgeSlideData *sld = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data; + EdgeSlideData *sld = edgeSlideFirstGet(t); const bool is_clamp = !(t->flag & T_ALT_TRANSFORM); /* Even mode */ @@ -7968,7 +7991,7 @@ static void drawEdgeSlide(TransInfo *t) static void doEdgeSlide(TransInfo *t, float perc) { EdgeSlideParams *slp = t->custom.mode.data; - EdgeSlideData *sld_active = TRANS_DATA_CONTAINER_FIRST_OK(t)->custom.mode.data; + EdgeSlideData *sld_active = edgeSlideFirstGet(t); slp->perc = perc; @@ -7979,6 +8002,11 @@ static void doEdgeSlide(TransInfo *t, float perc) const float perc_final = fabsf(perc); FOREACH_TRANS_DATA_CONTAINER (t, tc) { EdgeSlideData *sld = tc->custom.mode.data; + + if (sld == NULL) { + continue; + } + TransDataEdgeSlideVert *sv = sld->sv; for (int i = 0; i < sld->totsv; i++, sv++) { madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, sv->dir_side[side_index], perc_final); @@ -7992,6 +8020,11 @@ static void doEdgeSlide(TransInfo *t, float perc) const int side_index = sld_active->curr_side_unclamp; FOREACH_TRANS_DATA_CONTAINER (t, tc) { EdgeSlideData *sld = tc->custom.mode.data; + + if (sld == NULL) { + continue; + } + TransDataEdgeSlideVert *sv = sld->sv; for (int i = 0; i < sld->totsv; i++, sv++) { float dir_flip[3]; @@ -8028,6 +8061,11 @@ static void doEdgeSlide(TransInfo *t, float perc) FOREACH_TRANS_DATA_CONTAINER (t, tc) { EdgeSlideData *sld = tc->custom.mode.data; + + if (sld == NULL) { + continue; + } + TransDataEdgeSlideVert *sv = sld->sv; for (int i = 0; i < sld->totsv; i++, sv++) { if (sv->edge_len > FLT_EPSILON) { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index f7158244cc7..d13c0f8e8f1 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -7100,6 +7100,10 @@ void special_aftertrans_update(bContext *C, TransInfo *t) FOREACH_TRANS_DATA_CONTAINER (t, tc) { EdgeSlideData *sld = tc->custom.mode.data; + if (sld == NULL) { + continue; + } + /* Free temporary faces to avoid auto-merging and deleting * during cleanup - psy-fi. */ freeEdgeSlideTempFaces(sld); |