Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2016-02-01 07:15:10 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-02-01 07:23:29 +0300
commitc2508b0aaf38a511eb419e340b3aa8a6f981a8c4 (patch)
tree2bd523f510fd1794502fb822e7094577a5bf0315
parent17429dce0075a5863030f51741fc3c286ddace1d (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.
-rw-r--r--source/blender/editors/transform/transform.c121
-rw-r--r--source/blender/editors/transform/transform.h29
-rw-r--r--source/blender/editors/transform/transform_conversions.c131
-rw-r--r--source/blender/editors/transform/transform_generics.c28
-rw-r--r--source/blender/editors/transform/transform_snap.c2
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;