Commit: 5ca302cb0cb40506e1f8a5f22e9baa3738ab4a58
Author: Dalai Felinto
Date:   Tue Jul 16 22:23:43 2019 -0300
Branches: master
https://developer.blender.org/rB5ca302cb0cb40506e1f8a5f22e9baa3738ab4a58

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

===================================================================

M       source/blender/editors/transform/transform.c
M       source/blender/editors/transform/transform_conversions.c

===================================================================

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);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to