diff options
author | Campbell Barton <ideasman42@gmail.com> | 2016-02-01 07:15:10 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-02-01 07:23:29 +0300 |
commit | c2508b0aaf38a511eb419e340b3aa8a6f981a8c4 (patch) | |
tree | 2bd523f510fd1794502fb822e7094577a5bf0315 /source/blender/editors/transform | |
parent | 17429dce0075a5863030f51741fc3c286ddace1d (diff) |
Fix transform crash in rare cases
In some cases transform modes would use the custom-data pointer,
other times the transform conversion functions would.
However with some combinations (bone mirror + bend for eg),
both conversion & transform mode would use this pointer causing a crash.
Fix this by having 2 custom-data pointers:
one for the mode, another for the data-type.
This also simplifies time-slide which was conditionally mixing mode/type data in the one array.
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r-- | source/blender/editors/transform/transform.c | 121 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.h | 29 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 131 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_generics.c | 28 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_snap.c | 2 |
5 files changed, 160 insertions, 151 deletions
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index bc60a0c6107..307194ca592 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2858,7 +2858,7 @@ static void initBend(TransInfo *t) t->num.unit_type[0] = B_UNIT_ROTATION; t->num.unit_type[1] = B_UNIT_LENGTH; - t->flag |= T_NO_CONSTRAINT | T_FREE_CUSTOMDATA; + t->flag |= T_NO_CONSTRAINT; //copy_v3_v3(t->center, ED_view3d_cursor3d_get(t->scene, t->view)); calculateCenterCursor(t, t->center); @@ -2886,7 +2886,8 @@ static void initBend(TransInfo *t) data->warp_init_dist = len_v3v3(data->warp_end, data->warp_sta); - t->customData = data; + t->custom.mode.data = data; + t->custom.mode.use_free = true; } static eRedrawFlag handleEventBend(TransInfo *UNUSED(t), const wmEvent *event) @@ -2908,7 +2909,7 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2])) float warp_end_radius[3]; int i; char str[MAX_INFO_LEN]; - const struct BendCustomData *data = t->customData; + const struct BendCustomData *data = t->custom.mode.data; const bool is_clamp = (t->flag & T_ALT_TRANSFORM) == 0; union { @@ -3065,27 +3066,27 @@ static eRedrawFlag handleEventShear(TransInfo *t, const wmEvent *event) eRedrawFlag status = TREDRAW_NOTHING; if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) { - // Use customData pointer to signal Shear direction - if (t->customData == NULL) { + /* Use custom.mode.data pointer to signal Shear direction */ + if (t->custom.mode.data == NULL) { initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE); - t->customData = (void *)1; + t->custom.mode.data = (void *)1; } else { initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE); - t->customData = NULL; + t->custom.mode.data = NULL; } status = TREDRAW_HARD; } else if (event->type == XKEY && event->val == KM_PRESS) { initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE); - t->customData = NULL; + t->custom.mode.data = NULL; status = TREDRAW_HARD; } else if (event->type == YKEY && event->val == KM_PRESS) { initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE); - t->customData = (void *)1; + t->custom.mode.data = (void *)1; status = TREDRAW_HARD; } @@ -3131,7 +3132,7 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2])) unit_m3(smat); // Custom data signals shear direction - if (t->customData == NULL) + if (t->custom.mode.data == NULL) smat[1][0] = value; else smat[0][1] = value; @@ -5680,7 +5681,7 @@ static void slide_origdata_free_date( static void calcEdgeSlideCustomPoints(struct TransInfo *t) { - EdgeSlideData *sld = t->customData; + EdgeSlideData *sld = t->custom.mode.data; setCustomPoints(t, &t->mouse, sld->mval_end, sld->mval_start); @@ -6425,7 +6426,7 @@ static bool createEdgeSlideVerts_double_side(TransInfo *t, bool use_even, bool f sld->perc = 0.0f; - t->customData = sld; + t->custom.mode.data = sld; MEM_freeN(sv_table); @@ -6627,7 +6628,7 @@ static bool createEdgeSlideVerts_single_side(TransInfo *t, bool use_even, bool f sld->perc = 0.0f; - t->customData = sld; + t->custom.mode.data = sld; MEM_freeN(sv_table); @@ -6636,7 +6637,7 @@ static bool createEdgeSlideVerts_single_side(TransInfo *t, bool use_even, bool f void projectEdgeSlideData(TransInfo *t, bool is_final) { - EdgeSlideData *sld = t->customData; + EdgeSlideData *sld = t->custom.mode.data; SlideOrigData *sod = &sld->orig_data; if (sod->use_origfaces == false) { @@ -6651,9 +6652,9 @@ void freeEdgeSlideTempFaces(EdgeSlideData *sld) slide_origdata_free_date(&sld->orig_data); } -void freeEdgeSlideVerts(TransInfo *t) +void freeEdgeSlideVerts(TransInfo *UNUSED(t), TransCustomData *custom_data) { - EdgeSlideData *sld = t->customData; + EdgeSlideData *sld = custom_data->data; if (!sld) return; @@ -6665,7 +6666,7 @@ void freeEdgeSlideVerts(TransInfo *t) MEM_freeN(sld->sv); MEM_freeN(sld); - t->customData = NULL; + custom_data->data = NULL; } static void initEdgeSlide_ex(TransInfo *t, bool use_double_side, bool use_even, bool flipped, bool use_clamp) @@ -6689,12 +6690,12 @@ static void initEdgeSlide_ex(TransInfo *t, bool use_double_side, bool use_even, return; } - sld = t->customData; + sld = t->custom.mode.data; if (!sld) return; - t->customFree = freeEdgeSlideVerts; + t->custom.mode.free_cb = freeEdgeSlideVerts; /* set custom point first if you want value to be initialized by init */ calcEdgeSlideCustomPoints(t); @@ -6721,7 +6722,7 @@ static void initEdgeSlide(TransInfo *t) static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEvent *event) { if (t->mode == TFM_EDGE_SLIDE) { - EdgeSlideData *sld = t->customData; + EdgeSlideData *sld = t->custom.mode.data; if (sld) { switch (event->type) { @@ -6770,8 +6771,8 @@ static eRedrawFlag handleEventEdgeSlide(struct TransInfo *t, const struct wmEven static void drawEdgeSlide(TransInfo *t) { - if ((t->mode == TFM_EDGE_SLIDE) && t->customData) { - EdgeSlideData *sld = t->customData; + if ((t->mode == TFM_EDGE_SLIDE) && t->custom.mode.data) { + EdgeSlideData *sld = t->custom.mode.data; const bool is_clamp = !(t->flag & T_ALT_TRANSFORM); /* Even mode */ @@ -6886,7 +6887,7 @@ static void drawEdgeSlide(TransInfo *t) static void doEdgeSlide(TransInfo *t, float perc) { - EdgeSlideData *sld = t->customData; + EdgeSlideData *sld = t->custom.mode.data; TransDataEdgeSlideVert *svlist = sld->sv, *sv; int i; @@ -6959,7 +6960,7 @@ static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2])) char str[MAX_INFO_LEN]; size_t ofs = 0; float final; - EdgeSlideData *sld = t->customData; + EdgeSlideData *sld = t->custom.mode.data; bool flipped = sld->flipped; bool use_even = sld->use_even; const bool is_clamp = !(t->flag & T_ALT_TRANSFORM); @@ -7013,7 +7014,7 @@ static void applyEdgeSlide(TransInfo *t, const int UNUSED(mval[2])) static void calcVertSlideCustomPoints(struct TransInfo *t) { - VertSlideData *sld = t->customData; + VertSlideData *sld = t->custom.mode.data; TransDataVertSlideVert *sv = &sld->sv[sld->curr_sv_index]; const float *co_orig_3d = sv->co_orig_3d; @@ -7048,7 +7049,7 @@ static void calcVertSlideCustomPoints(struct TransInfo *t) */ static void calcVertSlideMouseActiveVert(struct TransInfo *t, const int mval[2]) { - VertSlideData *sld = t->customData; + VertSlideData *sld = t->custom.mode.data; float mval_fl[2] = {UNPACK2(mval)}; TransDataVertSlideVert *sv; @@ -7075,7 +7076,7 @@ static void calcVertSlideMouseActiveVert(struct TransInfo *t, const int mval[2]) */ static void calcVertSlideMouseActiveEdges(struct TransInfo *t, const int mval[2]) { - VertSlideData *sld = t->customData; + VertSlideData *sld = t->custom.mode.data; float imval_fl[2] = {UNPACK2(t->mouse.imval)}; float mval_fl[2] = {UNPACK2(mval)}; @@ -7209,7 +7210,7 @@ static bool createVertSlideVerts(TransInfo *t, bool use_even, bool flipped, bool sld->perc = 0.0f; - t->customData = sld; + t->custom.mode.data = sld; /* most likely will be set below */ unit_m4(sld->proj_mat); @@ -7233,7 +7234,7 @@ static bool createVertSlideVerts(TransInfo *t, bool use_even, bool flipped, bool void projectVertSlideData(TransInfo *t, bool is_final) { - VertSlideData *sld = t->customData; + VertSlideData *sld = t->custom.mode.data; SlideOrigData *sod = &sld->orig_data; if (sod->use_origfaces == false) { @@ -7248,9 +7249,9 @@ void freeVertSlideTempFaces(VertSlideData *sld) slide_origdata_free_date(&sld->orig_data); } -void freeVertSlideVerts(TransInfo *t) +void freeVertSlideVerts(TransInfo *UNUSED(t), TransCustomData *custom_data) { - VertSlideData *sld = t->customData; + VertSlideData *sld = custom_data->data; if (!sld) return; @@ -7270,7 +7271,7 @@ void freeVertSlideVerts(TransInfo *t) MEM_freeN(sld->sv); MEM_freeN(sld); - t->customData = NULL; + custom_data->data = NULL; } static void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use_clamp) @@ -7286,12 +7287,12 @@ static void initVertSlide_ex(TransInfo *t, bool use_even, bool flipped, bool use return; } - sld = t->customData; + sld = t->custom.mode.data; if (!sld) return; - t->customFree = freeVertSlideVerts; + t->custom.mode.free_cb = freeVertSlideVerts; /* set custom point first if you want value to be initialized by init */ calcVertSlideCustomPoints(t); @@ -7318,7 +7319,7 @@ static void initVertSlide(TransInfo *t) static eRedrawFlag handleEventVertSlide(struct TransInfo *t, const struct wmEvent *event) { if (t->mode == TFM_VERT_SLIDE) { - VertSlideData *sld = t->customData; + VertSlideData *sld = t->custom.mode.data; if (sld) { switch (event->type) { @@ -7378,8 +7379,8 @@ static eRedrawFlag handleEventVertSlide(struct TransInfo *t, const struct wmEven static void drawVertSlide(TransInfo *t) { - if ((t->mode == TFM_VERT_SLIDE) && t->customData) { - VertSlideData *sld = t->customData; + if ((t->mode == TFM_VERT_SLIDE) && t->custom.mode.data) { + VertSlideData *sld = t->custom.mode.data; const bool is_clamp = !(t->flag & T_ALT_TRANSFORM); /* Non-Prop mode */ @@ -7483,7 +7484,7 @@ static void drawVertSlide(TransInfo *t) static void doVertSlide(TransInfo *t, float perc) { - VertSlideData *sld = t->customData; + VertSlideData *sld = t->custom.mode.data; TransDataVertSlideVert *svlist = sld->sv, *sv; int i; @@ -7527,7 +7528,7 @@ static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2])) char str[MAX_INFO_LEN]; size_t ofs = 0; float final; - VertSlideData *sld = t->customData; + VertSlideData *sld = t->custom.mode.data; const bool flipped = sld->flipped; const bool use_even = sld->use_even; const bool is_clamp = !(t->flag & T_ALT_TRANSFORM); @@ -8277,10 +8278,34 @@ static void initTimeSlide(TransInfo *t) t->mode = TFM_TIME_SLIDE; t->transform = applyTimeSlide; - t->flag |= T_FREE_CUSTOMDATA; initMouseInputMode(t, &t->mouse, INPUT_NONE); + { + Scene *scene = t->scene; + float *range; + t->custom.mode.data = range = MEM_mallocN(sizeof(float[2]), "TimeSlide Min/Max"); + t->custom.mode.use_free = true; + + float min = 999999999.0f, max = -999999999.0f; + int i; + + TransData *td = t->data; + for (i = 0; i < t->total; i++, td++) { + if (min > *(td->val)) min = *(td->val); + if (max < *(td->val)) max = *(td->val); + } + + if (min == max) { + /* just use the current frame ranges */ + min = (float)PSFRA; + max = (float)PEFRA; + } + + range[0] = min; + range[1] = max; + } + /* num-input has max of (n-1) */ t->idx_max = 0; t->num.flag = 0; @@ -8304,8 +8329,9 @@ static void headerTimeSlide(TransInfo *t, const float sval, char str[MAX_INFO_LE outputNumInput(&(t->num), tvec, &t->scene->unit); } else { - float minx = *((float *)(t->customData)); - float maxx = *((float *)(t->customData) + 1); + const float *range = t->custom.mode.data; + float minx = range[0]; + float maxx = range[1]; float cval = t->values[0]; float val; @@ -8322,9 +8348,9 @@ static void applyTimeSlideValue(TransInfo *t, float sval) { TransData *td = t->data; int i; - - float minx = *((float *)(t->customData)); - float maxx = *((float *)(t->customData) + 1); + const float *range = t->custom.mode.data; + float minx = range[0]; + float maxx = range[1]; /* set value for drawing black line */ if (t->spacetype == SPACE_ACTION) { @@ -8369,8 +8395,9 @@ static void applyTimeSlide(TransInfo *t, const int mval[2]) { View2D *v2d = (View2D *)t->view; float cval[2], sval[2]; - float minx = *((float *)(t->customData)); - float maxx = *((float *)(t->customData) + 1); + const float *range = t->custom.mode.data; + float minx = range[0]; + float maxx = range[1]; char str[MAX_INFO_LEN]; /* calculate mouse co-ordinates */ diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index f6b4d7da57f..c6d801f7160 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -357,6 +357,12 @@ typedef struct MouseInput { } virtual_mval; } MouseInput; +typedef struct TransCustomData { + void *data; + void (*free_cb)(struct TransInfo *, struct TransCustomData *); + unsigned int use_free : 1; +} TransCustomData; + typedef struct TransInfo { int mode; /* current mode */ int flag; /* generic flags for special behaviors */ @@ -408,8 +414,22 @@ typedef struct TransInfo { struct Object *poseobj; /* if t->flag & T_POSE, this denotes pose object */ - void *customData; /* Per Transform custom data */ - void (*customFree)(struct TransInfo *); /* if a special free function is needed */ + /** + * Rule of thumb for choosing between mode/type: + * - If transform mode uses the data, assign to `mode` + * (typically in transform.c). + * - If conversion uses the data as an extension to the #TransData, assign to `type` + * (typically in transform_conversion.c). + */ + struct { + /* owned by the mode (grab, scale, bend... )*/ + union { + TransCustomData mode, first_elem; + }; + /* owned by the type (mesh, armature, nla...) */ + TransCustomData type; + } custom; +#define TRANS_CUSTOM_DATA_ELEM_MAX (sizeof(((TransInfo *)NULL)->custom) / sizeof(TransCustomData)) /*************** NEW STUFF *********************/ short launch_event; /* event type used to launch transform */ @@ -484,7 +504,6 @@ typedef struct TransInfo { #define T_2D_EDIT (1 << 15) #define T_CLIP_UV (1 << 16) -#define T_FREE_CUSTOMDATA (1 << 17) /* auto-ik is on */ #define T_AUTOIK (1 << 18) @@ -758,11 +777,11 @@ int getTransformOrientation_ex(const struct bContext *C, float normal[3], float int getTransformOrientation(const struct bContext *C, float normal[3], float plane[3]); void freeEdgeSlideTempFaces(EdgeSlideData *sld); -void freeEdgeSlideVerts(TransInfo *t); +void freeEdgeSlideVerts(TransInfo *t, TransCustomData *custom_data); void projectEdgeSlideData(TransInfo *t, bool is_final); void freeVertSlideTempFaces(VertSlideData *sld); -void freeVertSlideVerts(TransInfo *t); +void freeVertSlideVerts(TransInfo *t, TransCustomData *custom_data); void projectVertSlideData(TransInfo *t, bool is_final); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 4514171c991..df0edae9a56 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1088,7 +1088,7 @@ static void createTransPose(TransInfo *t, Object *ob) void restoreBones(TransInfo *t) { bArmature *arm = t->obedit->data; - BoneInitData *bid = t->customData; + BoneInitData *bid = t->custom.type.data; EditBone *ebo; while (bid->bone) { @@ -1177,8 +1177,8 @@ static void createTransArmatureVerts(TransInfo *t) td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransEditBone"); if (mirror) { - t->customData = bid = MEM_mallocN((total_mirrored + 1) * sizeof(BoneInitData), "BoneInitData"); - t->flag |= T_FREE_CUSTOMDATA; + t->custom.type.data = bid = MEM_mallocN((total_mirrored + 1) * sizeof(BoneInitData), "BoneInitData"); + t->custom.type.use_free = true; } i = 0; @@ -3087,9 +3087,8 @@ static void createTransNlaData(bContext *C, TransInfo *t) t->data = MEM_callocN(t->total * sizeof(TransData), "TransData(NLA Editor)"); td = t->data; - t->customData = MEM_callocN(t->total * sizeof(TransDataNla), "TransDataNla (NLA Editor)"); - tdn = t->customData; - t->flag |= T_FREE_CUSTOMDATA; + t->custom.type.data = tdn = MEM_callocN(t->total * sizeof(TransDataNla), "TransDataNla (NLA Editor)"); + t->custom.type.use_free = true; /* loop 2: build transdata array */ for (ale = anim_data.first; ale; ale = ale->next) { @@ -3550,15 +3549,9 @@ typedef struct tGPFtransdata { /* This function helps flush transdata written to tempdata into the gp-frames */ void flushTransIntFrameActionData(TransInfo *t) { - tGPFtransdata *tfd; + tGPFtransdata *tfd = t->custom.type.data; int i; - /* find the first one to start from */ - if (t->mode == TFM_TIME_SLIDE) - tfd = (tGPFtransdata *)((float *)(t->customData) + 2); - else - tfd = (tGPFtransdata *)(t->customData); - /* flush data! */ for (i = 0; i < t->total; i++, tfd++) { *(tfd->sdata) = iroundf(tfd->val); @@ -3726,20 +3719,8 @@ static void createTransActionData(bContext *C, TransInfo *t) td2d = t->data2d; if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) { - if (t->mode == TFM_TIME_SLIDE) { - t->customData = MEM_callocN((sizeof(float) * 2) + (sizeof(tGPFtransdata) * count), "TimeSlide + tGPFtransdata"); - t->flag |= T_FREE_CUSTOMDATA; - tfd = (tGPFtransdata *)((float *)(t->customData) + 2); - } - else { - t->customData = MEM_callocN(sizeof(tGPFtransdata) * count, "tGPFtransdata"); - t->flag |= T_FREE_CUSTOMDATA; - tfd = (tGPFtransdata *)(t->customData); - } - } - else if (t->mode == TFM_TIME_SLIDE) { - t->customData = MEM_callocN(sizeof(float) * 2, "TimeSlide Min/Max"); - t->flag |= T_FREE_CUSTOMDATA; + t->custom.type.data = tfd = MEM_callocN(sizeof(tGPFtransdata) * count, "tGPFtransdata"); + t->custom.type.use_free = true; } /* loop 2: build transdata array */ @@ -3781,31 +3762,6 @@ static void createTransActionData(bContext *C, TransInfo *t) td = ActionFCurveToTransData(td, &td2d, fcu, adt, t->frame_side, cfra, is_prop_edit, ypos); } } - - /* check if we're supposed to be setting minx/maxx for TimeSlide */ - if (t->mode == TFM_TIME_SLIDE) { - float min = 999999999.0f, max = -999999999.0f; - int i; - - td = t->data; - for (i = 0; i < count; i++, td++) { - if (min > *(td->val)) min = *(td->val); - if (max < *(td->val)) max = *(td->val); - } - - if (min == max) { - /* just use the current frame ranges */ - min = (float)PSFRA; - max = (float)PEFRA; - } - - /* minx/maxx values used by TimeSlide are stored as a - * calloced 2-float array in t->customData. This gets freed - * in postTrans (T_FREE_CUSTOMDATA). - */ - *((float *)(t->customData)) = min; - *((float *)(t->customData) + 1) = max; - } /* calculate distances for proportional editing */ if (is_prop_edit) { @@ -4158,12 +4114,12 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) t->data = MEM_callocN(t->total * sizeof(TransData), "TransData (Graph Editor)"); /* for each 2d vert a 3d vector is allocated, so that they can be treated just as if they were 3d verts */ t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransData2D (Graph Editor)"); - t->customData = MEM_callocN(t->total * sizeof(TransDataGraph), "TransDataGraph"); - t->flag |= T_FREE_CUSTOMDATA; + t->custom.type.data = MEM_callocN(t->total * sizeof(TransDataGraph), "TransDataGraph"); + t->custom.type.use_free = true; td = t->data; td2d = t->data2d; - tdg = t->customData; + tdg = t->custom.type.data; /* precompute space-conversion matrices for dealing with non-uniform scaling of Graph Editor */ unit_m3(mtx); @@ -4565,7 +4521,7 @@ void flushTransGraphData(TransInfo *t) int a; /* flush to 2d vector from internally used 3d vector */ - for (a = 0, td = t->data, td2d = t->data2d, tdg = t->customData; + for (a = 0, td = t->data, td2d = t->data2d, tdg = t->custom.type.data; a < t->total; a++, td++, td2d++, tdg++) { @@ -4928,7 +4884,7 @@ static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts) } -static void freeSeqData(TransInfo *t) +static void freeSeqData(TransInfo *t, TransCustomData *custom_data) { Editing *ed = BKE_sequencer_editing_get(t->scene, false); @@ -5089,11 +5045,11 @@ static void freeSeqData(TransInfo *t) } } - if ((t->customData != NULL) && (t->flag & T_FREE_CUSTOMDATA)) { - TransSeq *ts = t->customData; + if ((custom_data->data != NULL) && custom_data->use_free) { + TransSeq *ts = custom_data->data; MEM_freeN(ts->tdseq); - MEM_freeN(t->customData); - t->customData = NULL; + MEM_freeN(custom_data->data); + custom_data->data = NULL; } if (t->data) { MEM_freeN(t->data); // XXX postTrans usually does this @@ -5121,7 +5077,7 @@ static void createTransSeqData(bContext *C, TransInfo *t) return; } - t->customFree = freeSeqData; + t->custom.type.free_cb = freeSeqData; xmouse = (int)UI_view2d_region_to_view_x(v2d, t->mouse.imval[0]); @@ -5167,11 +5123,11 @@ static void createTransSeqData(bContext *C, TransInfo *t) return; } - t->customData = ts = MEM_mallocN(sizeof(TransSeq), "transseq"); + t->custom.type.data = ts = MEM_mallocN(sizeof(TransSeq), "transseq"); + t->custom.type.use_free = true; td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransSeq TransData"); td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransSeq TransData2D"); ts->tdseq = tdsq = MEM_callocN(t->total * sizeof(TransDataSeq), "TransSeq TransDataSeq"); - t->flag |= T_FREE_CUSTOMDATA; /* loop 2: build transdata array */ SeqToTransData_Recursive(t, ed->seqbasep, td, td2d, tdsq); @@ -5956,10 +5912,13 @@ void special_aftertrans_update(bContext *C, TransInfo *t) if (t->spacetype == SPACE_VIEW3D) { if (t->obedit) { + /* Special Exception: + * We don't normally access 't->custom.mode' here, but its needed in this case. */ + if (canceled == 0) { /* we need to delete the temporary faces before automerging */ if (t->mode == TFM_EDGE_SLIDE) { - EdgeSlideData *sld = t->customData; + EdgeSlideData *sld = t->custom.mode.data; /* handle multires re-projection, done * on transform completion since it's @@ -5972,7 +5931,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } else if (t->mode == TFM_VERT_SLIDE) { /* as above */ - VertSlideData *sld = t->customData; + VertSlideData *sld = t->custom.mode.data; projectVertSlideData(t, true); freeVertSlideTempFaces(sld); } @@ -5983,13 +5942,13 @@ void special_aftertrans_update(bContext *C, TransInfo *t) } else { if (t->mode == TFM_EDGE_SLIDE) { - EdgeSlideData *sld = t->customData; + EdgeSlideData *sld = t->custom.mode.data; sld->perc = 0.0; projectEdgeSlideData(t, false); } else if (t->mode == TFM_VERT_SLIDE) { - VertSlideData *sld = t->customData; + VertSlideData *sld = t->custom.mode.data; sld->perc = 0.0; projectVertSlideData(t, false); @@ -6749,16 +6708,15 @@ static void planeTrackToTransData(const int framenr, TransData *td, TransData2D } } -static void transDataTrackingFree(TransInfo *t) +static void transDataTrackingFree(TransInfo *UNUSED(t), TransCustomData *custom_data) { - TransDataTracking *tdt = t->customData; - - if (tdt) { + if (custom_data->data) { + TransDataTracking *tdt = custom_data->data; if (tdt->smarkers) MEM_freeN(tdt->smarkers); MEM_freeN(tdt); - t->customData = NULL; + custom_data->data = NULL; } } @@ -6810,9 +6768,9 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t) td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransTracking TransData"); td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransTracking TransData2D"); - tdt = t->customData = MEM_callocN(t->total * sizeof(TransDataTracking), "TransTracking TransDataTracking"); + tdt = t->custom.type.data = MEM_callocN(t->total * sizeof(TransDataTracking), "TransTracking TransDataTracking"); - t->customFree = transDataTrackingFree; + t->custom.type.free_cb = transDataTrackingFree; /* create actual data */ track = tracksbase->first; @@ -6947,9 +6905,8 @@ static void createTransTrackingCurvesData(bContext *C, TransInfo *t) td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransTracking TransData"); td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransTracking TransData2D"); - tdt = t->customData = MEM_callocN(t->total * sizeof(TransDataTracking), "TransTracking TransDataTracking"); - - t->customFree = transDataTrackingFree; + t->custom.type.data = tdt = MEM_callocN(t->total * sizeof(TransDataTracking), "TransTracking TransDataTracking"); + t->custom.type.free_cb = transDataTrackingFree; /* create actual data */ track = tracksbase->first; @@ -7013,10 +6970,11 @@ static void cancelTransTracking(TransInfo *t) { SpaceClip *sc = t->sa->spacedata.first; int i, framenr = ED_space_clip_get_clip_frame_number(sc); + TransDataTracking *tdt_array = t->custom.type.data; i = 0; while (i < t->total) { - TransDataTracking *tdt = (TransDataTracking *) t->customData + i; + TransDataTracking *tdt = &tdt_array[i]; if (tdt->mode == transDataTracking_ModeTracks) { MovieTrackingTrack *track = tdt->track; @@ -7073,7 +7031,7 @@ void flushTransTracking(TransInfo *t) cancelTransTracking(t); /* flush to 2d vector from internally used 3d vector */ - for (a = 0, td = t->data, td2d = t->data2d, tdt = t->customData; a < t->total; a++, td2d++, td++, tdt++) { + for (a = 0, td = t->data, td2d = t->data2d, tdt = t->custom.type.data; a < t->total; a++, td2d++, td++, tdt++) { if (tdt->mode == transDataTracking_ModeTracks) { float loc2d[2]; @@ -7404,9 +7362,8 @@ static void createTransMaskingData(bContext *C, TransInfo *t) /* for each 2d uv coord a 3d vector is allocated, so that they can be * treated just as if they were 3d verts */ td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransObData2D(Mask Editing)"); - tdm = t->customData = MEM_callocN(t->total * sizeof(TransDataMasking), "TransDataMasking(Mask Editing)"); - - t->flag |= T_FREE_CUSTOMDATA; + t->custom.type.data = tdm = MEM_callocN(t->total * sizeof(TransDataMasking), "TransDataMasking(Mask Editing)"); + t->custom.type.use_free = true; /* create data */ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { @@ -7468,7 +7425,7 @@ void flushTransMasking(TransInfo *t) inv[1] = 1.0f / asp[1]; /* flush to 2d vector from internally used 3d vector */ - for (a = 0, td = t->data2d, tdm = t->customData; a < t->total; a++, td++, tdm++) { + for (a = 0, td = t->data2d, tdm = t->custom.type.data; a < t->total; a++, td++, tdm++) { td->loc2d[0] = td->loc[0] * inv[0]; td->loc2d[1] = td->loc[1] * inv[1]; mul_m3_v2(tdm->parent_inverse_matrix, td->loc2d); @@ -7616,8 +7573,8 @@ static void createTransPaintCurveVerts(bContext *C, TransInfo *t) t->total = total; td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransData2D"); td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransData"); - tdpc = t->customData = MEM_callocN(t->total * sizeof(TransDataPaintCurve), "TransDataPaintCurve"); - t->flag |= T_FREE_CUSTOMDATA; + t->custom.type.data = tdpc = MEM_callocN(t->total * sizeof(TransDataPaintCurve), "TransDataPaintCurve"); + t->custom.type.use_free = true; for (pcp = pc->points, i = 0; i < pc->tot_points; i++, pcp++) { if (PC_IS_ANY_SEL(pcp)) { @@ -7649,7 +7606,7 @@ void flushTransPaintCurve(TransInfo *t) { int i; TransData2D *td2d = t->data2d; - TransDataPaintCurve *tdpc = (TransDataPaintCurve *)t->customData; + TransDataPaintCurve *tdpc = t->custom.type.data; for (i = 0; i < t->total; i++, tdpc++, td2d++) { PaintCurvePoint *pcp = tdpc->pcp; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index d43ec0994cb..8d1db148ce5 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -422,7 +422,7 @@ static void recalcData_graphedit(TransInfo *t) /* helper for recalcData() - for NLA Editor transforms */ static void recalcData_nla(TransInfo *t) { - TransDataNla *tdn = (TransDataNla *)t->customData; + TransDataNla *tdn = t->custom.type.data; SpaceNla *snla = (SpaceNla *)t->sa->spacedata.first; Scene *scene = t->scene; double secf = FPS; @@ -1055,10 +1055,10 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis void resetTransModal(TransInfo *t) { if (t->mode == TFM_EDGE_SLIDE) { - freeEdgeSlideVerts(t); + freeEdgeSlideVerts(t, &t->custom.mode); } else if (t->mode == TFM_VERT_SLIDE) { - freeVertSlideVerts(t); + freeVertSlideVerts(t, &t->custom.mode); } } @@ -1441,14 +1441,20 @@ void postTrans(bContext *C, TransInfo *t) if (t->draw_handle_cursor) WM_paint_cursor_end(CTX_wm_manager(C), t->draw_handle_cursor); - if (t->customFree) { - /* Can take over freeing t->data and data2d etc... */ - t->customFree(t); - BLI_assert(t->customData == NULL); - } - else if ((t->customData != NULL) && (t->flag & T_FREE_CUSTOMDATA)) { - MEM_freeN(t->customData); - t->customData = NULL; + /* Free all custom-data */ + { + TransCustomData *custom_data = &t->custom.first_elem; + for (int i = 0; i < TRANS_CUSTOM_DATA_ELEM_MAX; i++, custom_data++) { + if (custom_data->free_cb) { + /* Can take over freeing t->data and data2d etc... */ + custom_data->free_cb(t, custom_data); + BLI_assert(custom_data->data == NULL); + } + else if ((custom_data->data != NULL) && custom_data->use_free) { + MEM_freeN(custom_data->data); + custom_data->data = NULL; + } + } } /* postTrans can be called when nothing is selected, so data is NULL already */ diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 8e02a402bf8..eb3b08ef5ef 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -2528,7 +2528,7 @@ void snapSequenceBounds(TransInfo *t, const int mval[2]) float xmouse, ymouse; int frame; int mframe; - TransSeq *ts = t->customData; + TransSeq *ts = t->custom.type.data; /* reuse increment, strictly speaking could be another snap mode, but leave as is */ if (!(t->modifiers & MOD_SNAP_INVERT)) return; |