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:
Diffstat (limited to 'source/blender/editors/transform/transform_conversions.c')
-rw-r--r--source/blender/editors/transform/transform_conversions.c894
1 files changed, 563 insertions, 331 deletions
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index fff124c8995..936985d4cb9 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -130,7 +130,7 @@
*/
static void transform_around_single_fallback(TransInfo *t)
{
- if ((t->total == 1) &&
+ if ((t->data_len_all == 1) &&
(ELEM(t->around, V3D_AROUND_CENTER_BOUNDS, V3D_AROUND_CENTER_MEAN, V3D_AROUND_ACTIVE)) &&
(ELEM(t->mode, TFM_RESIZE, TFM_ROTATION, TFM_TRACKBALL)))
{
@@ -171,27 +171,31 @@ static int trans_data_compare_rdist(const void *a, const void *b)
void sort_trans_data_dist(TransInfo *t)
{
- TransData *start = t->data;
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ TransData *start = tc->data;
int i;
- for (i = 0; i < t->total && start->flag & TD_SELECTED; i++)
+ for (i = 0; i < tc->data_len && start->flag & TD_SELECTED; i++) {
start++;
-
- if (i < t->total) {
+ }
+
+ if (i < tc->data_len) {
if (t->flag & T_PROP_CONNECTED)
- qsort(start, t->total - i, sizeof(TransData), trans_data_compare_dist);
+ qsort(start, tc->data_len - i, sizeof(TransData), trans_data_compare_dist);
else
- qsort(start, t->total - i, sizeof(TransData), trans_data_compare_rdist);
+ qsort(start, tc->data_len - i, sizeof(TransData), trans_data_compare_rdist);
+ }
}
}
static void sort_trans_data(TransInfo *t)
{
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData *sel, *unsel;
TransData temp;
- unsel = t->data;
- sel = t->data;
- sel += t->total - 1;
+ unsel = tc->data;
+ sel = tc->data;
+ sel += tc->data_len - 1;
while (sel > unsel) {
while (unsel->flag & TD_SELECTED) {
unsel++;
@@ -211,13 +215,13 @@ static void sort_trans_data(TransInfo *t)
sel--;
unsel++;
}
+ }
}
/* distance calculated from not-selected vertex to nearest selected vertex
* warning; this is loops inside loop, has minor N^2 issues, but by sorting list it is OK */
static void set_prop_dist(TransInfo *t, const bool with_dist)
{
- TransData *tob;
int a;
float _proj_vec[3];
@@ -234,7 +238,9 @@ static void set_prop_dist(TransInfo *t, const bool with_dist)
}
}
- for (a = 0, tob = t->data; a < t->total; a++, tob++) {
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ TransData *tob = tc->data;
+ for (a = 0; a < tc->data_len; a++, tob++) {
tob->rdist = 0.0f; // init, it was mallocced
@@ -245,7 +251,7 @@ static void set_prop_dist(TransInfo *t, const bool with_dist)
tob->rdist = -1.0f; // signal for next loop
- for (i = 0, td = t->data; i < t->total; i++, td++) {
+ for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
if (td->flag & TD_SELECTED) {
if (use_island) {
sub_v3_v3v3(vec, tob->iloc, td->iloc);
@@ -279,6 +285,7 @@ static void set_prop_dist(TransInfo *t, const bool with_dist)
}
}
}
+ }
}
/* ************************** CONVERSIONS ************************* */
@@ -296,26 +303,32 @@ static void createTransTexspace(TransInfo *t)
ob = OBACT(view_layer);
if (ob == NULL) { // Shouldn't logically happen, but still...
- t->total = 0;
+ t->data_len_all = 0;
return;
}
id = ob->data;
if (id == NULL || !ELEM(GS(id->name), ID_ME, ID_CU, ID_MB)) {
BKE_report(t->reports, RPT_ERROR, "Unsupported object type for text-space transform");
- t->total = 0;
+ t->data_len_all = 0;
return;
}
if (BKE_object_obdata_is_libdata(ob)) {
BKE_report(t->reports, RPT_ERROR, "Linked data can't text-space transform");
- t->total = 0;
+ t->data_len_all = 0;
return;
}
- t->total = 1;
- td = t->data = MEM_callocN(sizeof(TransData), "TransTexspace");
- td->ext = t->ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
+
+ {
+ TransDataContainer *tc = t->data_container = MEM_callocN(sizeof(*t->data_container), __func__);
+ tc->data_len = 1;
+ td = tc->data = MEM_callocN(sizeof(TransData), "TransTexspace");
+ td->ext = tc->data_ext = MEM_callocN(sizeof(TransDataExtension), "TransTexspace");
+ }
+
+ t->data_len_all = 1;
td->flag = TD_SELECTED;
copy_v3_v3(td->center, ob->obmat[3]);
@@ -340,7 +353,9 @@ static void createTransTexspace(TransInfo *t)
static void createTransEdge(TransInfo *t)
{
- BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
TransData *td = NULL;
BMEdge *eed;
BMIter iter;
@@ -356,29 +371,31 @@ static void createTransEdge(TransInfo *t)
}
}
- if (countsel == 0)
- return;
+ if (countsel == 0) {
+ tc->data_len = 0;
+ continue;
+ }
if (is_prop_edit) {
- t->total = count;
+ tc->data_len = count;
}
else {
- t->total = countsel;
+ tc->data_len = countsel;
}
- td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransCrease");
+ td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransCrease");
- copy_m3_m4(mtx, t->obedit->obmat);
+ copy_m3_m4(mtx, tc->obedit->obmat);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
/* create data we need */
if (t->mode == TFM_BWEIGHT) {
- BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_EDGE_BWEIGHT);
+ BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_BWEIGHT);
cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
}
else { //if (t->mode == TFM_CREASE) {
BLI_assert(t->mode == TFM_CREASE);
- BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_EDGE_CREASE);
+ BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_CREASE);
cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
}
@@ -408,6 +425,7 @@ static void createTransEdge(TransInfo *t)
td++;
}
}
+ }
}
/* ********************* pose mode ************* */
@@ -523,7 +541,7 @@ static short apply_targetless_ik(Object *ob)
return apply;
}
-static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransData *td)
+static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, TransDataContainer *tc, TransData *td)
{
Bone *bone = pchan->bone;
float pmat[3][3], omat[3][3];
@@ -634,7 +652,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
normalize_m3(td->axismtx);
if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
- bArmature *arm = t->poseobj->data;
+ bArmature *arm = tc->poseobj->data;
if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) {
td->loc = NULL;
@@ -828,15 +846,20 @@ void transform_autoik_update(TransInfo *t, short mode)
}
}
- /* sanity checks (don't assume t->poseobj is set, or that it is an armature) */
- if (ELEM(NULL, t->poseobj, t->poseobj->pose))
- return;
-
/* apply to all pose-channels */
bool changed = false;
- for (pchan = t->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) {
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+
+ /* sanity checks (don't assume t->poseobj is set, or that it is an armature) */
+ if (ELEM(NULL, tc->poseobj, tc->poseobj->pose)) {
+ continue;
+ }
+
+ for (pchan = tc->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) {
changed |= pchan_autoik_adjust(pchan, *chainlen);
}
+ }
if (changed) {
/* TODO(sergey): Consider doing partial update only. */
@@ -1045,9 +1068,28 @@ static short pose_grab_with_ik(Object *ob)
}
-/* only called with pose mode active object now */
-static void createTransPose(TransInfo *t, Object *ob)
+/**
+ * When objects array is NULL, use 't->data_container' as is.
+ */
+static void createTransPose(TransInfo *t, Object **objects, uint objects_len)
{
+ if (objects != NULL) {
+ if (t->data_container) {
+ MEM_freeN(t->data_container);
+ }
+ t->data_container = MEM_callocN(sizeof(*t->data_container) * objects_len, __func__);
+ t->data_container_len = objects_len;
+ int th_index;
+ FOREACH_TRANS_DATA_CONTAINER_INDEX (t, tc, th_index) {
+ tc->poseobj = objects[th_index];
+ }
+ }
+
+ t->data_len_all = 0;
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ Object *ob = tc->poseobj;
+
bArmature *arm;
bPoseChannel *pchan;
TransData *td;
@@ -1055,11 +1097,12 @@ static void createTransPose(TransInfo *t, Object *ob)
short ik_on = 0;
int i;
- t->total = 0;
/* check validity of state */
- arm = BKE_armature_from_object(ob);
- if ((arm == NULL) || (ob->pose == NULL)) return;
+ arm = BKE_armature_from_object(tc->poseobj);
+ if ((arm == NULL) || (ob->pose == NULL)) {
+ continue;
+ }
if (arm->flag & ARM_RESTPOS) {
if (ELEM(t->mode, TFM_DUMMY, TFM_BONESIZE) == 0) {
@@ -1075,45 +1118,51 @@ static void createTransPose(TransInfo *t, Object *ob)
}
/* set flags and count total (warning, can change transform to rotate) */
- t->total = count_set_pose_transflags(&t->mode, t->around, ob);
+ tc->data_len = count_set_pose_transflags(&t->mode, t->around, ob);
- if (t->total == 0) return;
+ if (tc->data_len == 0) {
+ continue;
+ }
- t->flag |= T_POSE;
- t->poseobj = ob; /* we also allow non-active objects to be transformed, in weightpaint */
-
- /* disable PET, its not usable in pose mode yet [#32444] */
- t->flag &= ~T_PROP_EDIT_ALL;
+ tc->poseobj = ob; /* we also allow non-active objects to be transformed, in weightpaint */
/* init trans data */
- td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransPoseBone");
- tdx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "TransPoseBoneExt");
- for (i = 0; i < t->total; i++, td++, tdx++) {
+ td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransPoseBone");
+ tdx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "TransPoseBoneExt");
+ for (i = 0; i < tc->data_len; i++, td++, tdx++) {
td->ext = tdx;
td->val = NULL;
}
/* use pose channels to fill trans data */
- td = t->data;
+ td = tc->data;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone->flag & BONE_TRANSFORM) {
- add_pose_transdata(t, pchan, ob, td);
+ add_pose_transdata(t, pchan, ob, tc, td);
td++;
}
}
- if (td != (t->data + t->total)) {
+ if (td != (tc->data + tc->data_len)) {
BKE_report(t->reports, RPT_DEBUG, "Bone selection count error");
}
/* initialize initial auto=ik chainlen's? */
- if (ik_on) transform_autoik_update(t, 0);
+ if (ik_on) {
+ transform_autoik_update(t, 0);
+ }
+ }
+
+ t->flag |= T_POSE;
+ /* disable PET, its not usable in pose mode yet [#32444] */
+ t->flag &= ~T_PROP_EDIT_ALL;
+
}
-void restoreBones(TransInfo *t)
+void restoreBones(TransDataContainer *tc)
{
- bArmature *arm = t->obedit->data;
- BoneInitData *bid = t->custom.type.data;
+ bArmature *arm = tc->obedit->data;
+ BoneInitData *bid = tc->custom.type.data;
EditBone *ebo;
while (bid->bone) {
@@ -1154,8 +1203,9 @@ void restoreBones(TransInfo *t)
/* ********************* armature ************** */
static void createTransArmatureVerts(TransInfo *t)
{
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
EditBone *ebo, *eboflip;
- bArmature *arm = t->obedit->data;
+ bArmature *arm = tc->obedit->data;
ListBase *edbo = arm->edbo;
TransData *td, *td_old;
float mtx[3][3], smtx[3][3], bonemat[3][3];
@@ -1164,46 +1214,48 @@ static void createTransArmatureVerts(TransInfo *t)
int oldtot;
BoneInitData *bid;
- t->total = 0;
+ tc->data_len = 0;
for (ebo = edbo->first; ebo; ebo = ebo->next) {
- oldtot = t->total;
+ oldtot = tc->data_len;
if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) {
if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
if (ebo->flag & BONE_SELECTED)
- t->total++;
+ tc->data_len++;
}
else if (t->mode == TFM_BONE_ROLL) {
if (ebo->flag & BONE_SELECTED)
- t->total++;
+ tc->data_len++;
}
else {
if (ebo->flag & BONE_TIPSEL)
- t->total++;
+ tc->data_len++;
if (ebo->flag & BONE_ROOTSEL)
- t->total++;
+ tc->data_len++;
}
}
- if (mirror && (oldtot < t->total)) {
+ if (mirror && (oldtot < tc->data_len)) {
eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo);
if (eboflip)
total_mirrored++;
}
}
- if (!t->total) return;
+ if (!tc->data_len) {
+ continue;
+ }
transform_around_single_fallback(t);
- copy_m3_m4(mtx, t->obedit->obmat);
+ copy_m3_m4(mtx, tc->obedit->obmat);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
- td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransEditBone");
+ td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransEditBone");
if (mirror) {
- t->custom.type.data = bid = MEM_mallocN((total_mirrored + 1) * sizeof(BoneInitData), "BoneInitData");
- t->custom.type.use_free = true;
+ tc->custom.type.data = bid = MEM_mallocN((total_mirrored + 1) * sizeof(BoneInitData), "BoneInitData");
+ tc->custom.type.use_free = true;
}
i = 0;
@@ -1226,7 +1278,7 @@ static void createTransArmatureVerts(TransInfo *t)
td->loc = NULL;
td->ext = NULL;
- td->ob = t->obedit;
+ td->ob = tc->obedit;
td++;
}
@@ -1241,7 +1293,7 @@ static void createTransArmatureVerts(TransInfo *t)
td->loc = NULL;
td->ext = NULL;
- td->ob = t->obedit;
+ td->ob = tc->obedit;
td++;
}
@@ -1272,7 +1324,7 @@ static void createTransArmatureVerts(TransInfo *t)
normalize_m3(td->axismtx);
td->ext = NULL;
- td->ob = t->obedit;
+ td->ob = tc->obedit;
td++;
}
@@ -1287,7 +1339,7 @@ static void createTransArmatureVerts(TransInfo *t)
td->flag = TD_SELECTED;
td->ext = NULL;
- td->ob = t->obedit;
+ td->ob = tc->obedit;
td++;
}
@@ -1326,7 +1378,7 @@ static void createTransArmatureVerts(TransInfo *t)
td->ext = NULL;
td->val = NULL;
- td->ob = t->obedit;
+ td->ob = tc->obedit;
td++;
}
@@ -1348,7 +1400,7 @@ static void createTransArmatureVerts(TransInfo *t)
td->ext = NULL;
td->val = NULL;
- td->ob = t->obedit;
+ td->ob = tc->obedit;
td++;
}
@@ -1375,13 +1427,15 @@ static void createTransArmatureVerts(TransInfo *t)
/* trick to terminate iteration */
bid[total_mirrored].bone = NULL;
}
+ }
}
/* ********************* meta elements ********* */
static void createTransMBallVerts(TransInfo *t)
{
- MetaBall *mb = (MetaBall *)t->obedit->data;
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ MetaBall *mb = (MetaBall *)tc->obedit->data;
MetaElem *ml;
TransData *td;
TransDataExtension *tx;
@@ -1396,15 +1450,17 @@ static void createTransMBallVerts(TransInfo *t)
}
/* note: in prop mode we need at least 1 selected */
- if (countsel == 0) return;
+ if (countsel == 0) {
+ continue;
+ }
- if (is_prop_edit) t->total = count;
- else t->total = countsel;
+ if (is_prop_edit) tc->data_len = count;
+ else tc->data_len = countsel;
- td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(MBall EditMode)");
- tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "MetaElement_TransExtension");
+ td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(MBall EditMode)");
+ tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "MetaElement_TransExtension");
- copy_m3_m4(mtx, t->obedit->obmat);
+ copy_m3_m4(mtx, tc->obedit->obmat);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
for (ml = mb->editelems->first; ml; ml = ml->next) {
@@ -1449,6 +1505,7 @@ static void createTransMBallVerts(TransInfo *t)
tx++;
}
}
+ }
}
/* ********************* curve/surface ********* */
@@ -1555,7 +1612,9 @@ static int bezt_select_to_transform_triple_flag(
static void createTransCurveVerts(TransInfo *t)
{
- Curve *cu = t->obedit->data;
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+
+ Curve *cu = tc->obedit->data;
TransData *td = NULL;
Nurb *nu;
BezTriple *bezt;
@@ -1599,18 +1658,21 @@ static void createTransCurveVerts(TransInfo *t)
}
}
/* note: in prop mode we need at least 1 selected */
- if (countsel == 0) return;
+ if (countsel == 0) {
+ tc->data_len = 0;
+ continue;
+ }
- if (is_prop_edit) t->total = count;
- else t->total = countsel;
- t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Curve EditMode)");
+ if (is_prop_edit) tc->data_len = count;
+ else tc->data_len = countsel;
+ tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Curve EditMode)");
transform_around_single_fallback(t);
- copy_m3_m4(mtx, t->obedit->obmat);
+ copy_m3_m4(mtx, tc->obedit->obmat);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
- td = t->data;
+ td = tc->data;
for (nu = nurbs->first; nu; nu = nu->next) {
if (nu->type == CU_BEZIER) {
TransData *head, *tail;
@@ -1819,7 +1881,7 @@ static void createTransCurveVerts(TransInfo *t)
calc_distanceCurveVerts(head, tail - 1);
}
}
-
+ }
#undef SEL_F1
#undef SEL_F2
#undef SEL_F3
@@ -1829,7 +1891,9 @@ static void createTransCurveVerts(TransInfo *t)
static void createTransLatticeVerts(TransInfo *t)
{
- Lattice *latt = ((Lattice *)t->obedit->data)->editlatt->latt;
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+
+ Lattice *latt = ((Lattice *)tc->obedit->data)->editlatt->latt;
TransData *td = NULL;
BPoint *bp;
float mtx[3][3], smtx[3][3];
@@ -1850,14 +1914,14 @@ static void createTransLatticeVerts(TransInfo *t)
/* note: in prop mode we need at least 1 selected */
if (countsel == 0) return;
- if (is_prop_edit) t->total = count;
- else t->total = countsel;
- t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Lattice EditMode)");
+ if (is_prop_edit) tc->data_len = count;
+ else tc->data_len = countsel;
+ tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Lattice EditMode)");
- copy_m3_m4(mtx, t->obedit->obmat);
+ copy_m3_m4(mtx, tc->obedit->obmat);
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
- td = t->data;
+ td = tc->data;
bp = latt->def;
a = latt->pntsu * latt->pntsv * latt->pntsw;
while (a--) {
@@ -1884,11 +1948,14 @@ static void createTransLatticeVerts(TransInfo *t)
}
bp++;
}
+ }
}
/* ******************* particle edit **************** */
static void createTransParticleVerts(bContext *C, TransInfo *t)
{
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+
TransData *td = NULL;
TransDataExtension *tx;
Object *ob = CTX_data_active_object(C);
@@ -1936,13 +2003,13 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
/* note: in prop mode we need at least 1 selected */
if (hasselected == 0) return;
- t->total = count;
- td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Particle Mode)");
+ tc->data_len = count;
+ td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Particle Mode)");
if (t->mode == TFM_BAKE_TIME)
- tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "Particle_TransExtension");
+ tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "Particle_TransExtension");
else
- tx = t->ext = NULL;
+ tx = tc->data_ext = NULL;
unit_m4(mat);
@@ -2003,10 +2070,13 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
if (is_prop_edit && head != tail)
calc_distanceCurveVerts(head, tail - 1);
}
+ }
}
void flushTransParticles(TransInfo *t)
{
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+
Scene *scene = t->scene;
ViewLayer *view_layer = t->view_layer;
Object *ob = OBACT(view_layer);
@@ -2025,7 +2095,7 @@ void flushTransParticles(TransInfo *t)
/* we do transform in world space, so flush world space position
* back to particle local space (only for hair particles) */
- td = t->data;
+ td = tc->data;
for (i = 0, point = edit->points; i < edit->totpoint; i++, point++, td++) {
if (!(point->flag & PEP_TRANSFORM)) continue;
@@ -2050,6 +2120,7 @@ void flushTransParticles(TransInfo *t)
}
PE_update_object(&t->eval_ctx, scene, OBACT(view_layer), 1);
+ }
}
/* ********************* mesh ****************** */
@@ -2459,10 +2530,12 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx
static void createTransEditVerts(TransInfo *t)
{
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+
TransData *tob = NULL;
TransDataExtension *tx = NULL;
- BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
- Mesh *me = t->obedit->data;
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ Mesh *me = tc->obedit->data;
BMesh *bm = em->bm;
BMVert *eve;
BMIter iter;
@@ -2486,8 +2559,11 @@ static void createTransEditVerts(TransInfo *t)
int *dists_index = NULL;
if (t->flag & T_MIRROR) {
- EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, use_topology);
- mirror = 1;
+ /* TODO(campbell): xform: We need support for many mirror objects at once! */
+ if (tc->is_active) {
+ EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, use_topology);
+ mirror = 1;
+ }
}
/**
@@ -2501,7 +2577,7 @@ static void createTransEditVerts(TransInfo *t)
}
if (t->mode == TFM_BWEIGHT) {
- BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_VERT_BWEIGHT);
+ BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_VERT_BWEIGHT);
cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
}
@@ -2513,7 +2589,7 @@ static void createTransEditVerts(TransInfo *t)
}
}
- t->total = count;
+ tc->data_len = count;
/* allocating scratch arrays */
if (prop_mode & T_PROP_CONNECTED) {
@@ -2524,20 +2600,19 @@ static void createTransEditVerts(TransInfo *t)
}
}
else {
- t->total = bm->totvertsel;
+ tc->data_len = bm->totvertsel;
}
- tob = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Mesh EditMode)");
+ tob = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Mesh EditMode)");
if (ELEM(t->mode, TFM_SKIN_RESIZE, TFM_SHRINKFATTEN)) {
/* warning, this is overkill, we only need 2 extra floats,
* but this stores loads of extra stuff, for TFM_SHRINKFATTEN its even more overkill
* since we may not use the 'alt' transform mode to maintain shell thickness,
* but with generic transform code its hard to lazy init vars */
- tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension),
- "TransObData ext");
+ tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "TransObData ext");
}
- copy_m3_m4(mtx, t->obedit->obmat);
+ copy_m3_m4(mtx, tc->obedit->obmat);
/* we use a pseudoinverse so that when one of the axes is scaled to 0,
* matrix inversion still works and we can still moving along the other */
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
@@ -2557,12 +2632,12 @@ static void createTransEditVerts(TransInfo *t)
}
/* detect CrazySpace [tm] */
- if (modifiers_getCageIndex(t->scene, t->obedit, NULL, 1) != -1) {
+ if (modifiers_getCageIndex(t->scene, tc->obedit, NULL, 1) != -1) {
int totleft = -1;
- if (modifiers_isCorrectableDeformed(t->scene, t->obedit)) {
+ if (modifiers_isCorrectableDeformed(t->scene, tc->obedit)) {
/* check if we can use deform matrices for modifier from the
* start up to stack, they are more accurate than quats */
- totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(&t->eval_ctx, t->scene, t->obedit, em, &defmats, &defcos);
+ totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(&t->eval_ctx, t->scene, tc->obedit, em, &defmats, &defcos);
}
/* if we still have more modifiers, also do crazyspace
@@ -2575,7 +2650,7 @@ static void createTransEditVerts(TransInfo *t)
if (totleft > 0)
#endif
{
- mappedcos = BKE_crazyspace_get_mapped_editverts(&t->eval_ctx, t->scene, t->obedit);
+ mappedcos = BKE_crazyspace_get_mapped_editverts(&t->eval_ctx, t->scene, tc->obedit);
quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats");
BKE_crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats, !prop_mode);
if (mappedcos)
@@ -2675,8 +2750,8 @@ static void createTransEditVerts(TransInfo *t)
}
if (mirror != 0) {
- tob = t->data;
- for (a = 0; a < t->total; a++, tob++) {
+ tob = tc->data;
+ for (a = 0; a < tc->data_len; a++, tob++) {
if (ABS(tob->loc[0]) <= 0.00001f) {
tob->flag |= TD_MIRROR_EDGE;
}
@@ -2697,12 +2772,15 @@ cleanup:
if (t->flag & T_MIRROR) {
EDBM_verts_mirror_cache_end(em);
}
+ }
}
/* *** NODE EDITOR *** */
void flushTransNodes(TransInfo *t)
{
const float dpi_fac = UI_DPI_FAC;
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
int a;
TransData *td;
TransData2D *td2d;
@@ -2710,7 +2788,7 @@ void flushTransNodes(TransInfo *t)
applyGridAbsolute(t);
/* flush to 2d vector from internally used 3d vector */
- for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) {
+ for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
bNode *node = td->extra;
float locx, locy;
@@ -2732,11 +2810,12 @@ void flushTransNodes(TransInfo *t)
node->locy = locy;
}
}
-
+
/* handle intersection with noodles */
- if (t->total == 1) {
+ if (tc->data_len == 1) {
ED_node_link_intersect_test(t->sa, 1);
}
+ }
}
/* *** SEQUENCE EDITOR *** */
@@ -2765,13 +2844,14 @@ BLI_INLINE void trans_update_seq(Scene *sce, Sequence *seq, int old_start, int s
void flushTransSeq(TransInfo *t)
{
ListBase *seqbasep = BKE_sequencer_editing_get(t->scene, false)->seqbasep; /* Editing null check already done */
+
int a, new_frame;
TransData *td = NULL;
TransData2D *td2d = NULL;
TransDataSeq *tdsq = NULL;
Sequence *seq;
-
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
/* prevent updating the same seq twice
* if the transdata order is changed this will mess up
@@ -2780,7 +2860,7 @@ void flushTransSeq(TransInfo *t)
int old_start_prev = 0, sel_flag_prev = 0;
/* flush to 2d vector from internally used 3d vector */
- for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) {
+ for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
int old_start;
tdsq = (TransDataSeq *)td->extra;
seq = tdsq->seq;
@@ -2853,8 +2933,8 @@ void flushTransSeq(TransInfo *t)
}
/* update effects inside meta's */
- for (a = 0, seq_prev = NULL, td = t->data, td2d = t->data2d;
- a < t->total;
+ for (a = 0, seq_prev = NULL, td = tc->data, td2d = tc->data_2d;
+ a < tc->data_len;
a++, td++, td2d++, seq_prev = seq)
{
tdsq = (TransDataSeq *)td->extra;
@@ -2870,7 +2950,7 @@ void flushTransSeq(TransInfo *t)
/* need to do the overlap check in a new loop otherwise adjacent strips
* will not be updated and we'll get false positives */
seq_prev = NULL;
- for (a = 0, td = t->data, td2d = t->data2d; a < t->total; a++, td++, td2d++) {
+ for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
tdsq = (TransDataSeq *)td->extra;
seq = tdsq->seq;
@@ -2931,22 +3011,27 @@ static void createTransUVs(bContext *C, TransInfo *t)
Image *ima = CTX_data_edit_image(C);
Scene *scene = t->scene;
ToolSettings *ts = CTX_data_tool_settings(C);
+
+ const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
+ const bool is_prop_connected = (t->flag & T_PROP_CONNECTED) != 0;
+ const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS);
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+
TransData *td = NULL;
TransData2D *td2d = NULL;
- BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
BMFace *efa;
BMIter iter, liter;
UvElementMap *elementmap = NULL;
BLI_bitmap *island_enabled = NULL;
struct { float co[2]; int co_num; } *island_center = NULL;
int count = 0, countsel = 0, count_rejected = 0;
- const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
- const bool is_prop_connected = (t->flag & T_PROP_CONNECTED) != 0;
- const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS);
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
- if (!ED_space_image_show_uvedit(sima, t->obedit))
- return;
+ if (!ED_space_image_show_uvedit(sima, tc->obedit)) {
+ continue;
+ }
/* count */
if (is_prop_connected || is_island_center) {
@@ -2969,7 +3054,7 @@ static void createTransUVs(bContext *C, TransInfo *t)
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BMLoop *l;
- if (!uvedit_face_visible_test(scene, t->obedit, ima, efa)) {
+ if (!uvedit_face_visible_test(scene, tc->obedit, ima, efa)) {
BM_elem_flag_disable(efa, BM_ELEM_TAG);
continue;
}
@@ -3017,17 +3102,17 @@ static void createTransUVs(bContext *C, TransInfo *t)
}
}
- t->total = (is_prop_edit) ? count : countsel;
- t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(UV Editing)");
+ tc->data_len = (is_prop_edit) ? count : countsel;
+ tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(UV Editing)");
/* for each 2d uv coord 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), "TransObData2D(UV Editing)");
+ tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransObData2D(UV Editing)");
if (sima->flag & SI_CLIP_UV)
t->flag |= T_CLIP_UV;
- td = t->data;
- td2d = t->data2d;
+ td = tc->data;
+ td2d = tc->data_2d;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
BMLoop *l;
@@ -3065,12 +3150,16 @@ static void createTransUVs(bContext *C, TransInfo *t)
}
if (is_prop_connected) {
- t->total -= count_rejected;
+ tc->data_len -= count_rejected;
}
- if (sima->flag & SI_LIVE_UNWRAP)
- ED_uvedit_live_unwrap_begin(t->scene, t->obedit);
-
+ if (sima->flag & SI_LIVE_UNWRAP) {
+ /* TODO(campbell): xform: Only active object currently!
+ * it uses a static variable. */
+ if (tc->is_active) {
+ ED_uvedit_live_unwrap_begin(t->scene, tc->obedit);
+ }
+ }
finally:
if (is_prop_connected || is_island_center) {
@@ -3084,15 +3173,18 @@ finally:
MEM_freeN(island_center);
}
}
+ }
}
void flushTransUVs(TransInfo *t)
{
SpaceImage *sima = t->sa->spacedata.first;
+ const bool use_pixel_snap = ((sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL));
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
TransData2D *td;
int a;
float aspect_inv[2], size[2];
- const bool use_pixel_snap = ((sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL));
aspect_inv[0] = 1.0f / t->aspect[0];
aspect_inv[1] = 1.0f / t->aspect[1];
@@ -3105,7 +3197,7 @@ void flushTransUVs(TransInfo *t)
}
/* flush to 2d vector from internally used 3d vector */
- for (a = 0, td = t->data2d; a < t->total; a++, td++) {
+ for (a = 0, td = tc->data_2d; a < tc->data_len; a++, td++) {
td->loc2d[0] = td->loc[0] * aspect_inv[0];
td->loc2d[1] = td->loc[1] * aspect_inv[1];
@@ -3114,12 +3206,11 @@ void flushTransUVs(TransInfo *t)
td->loc2d[1] = roundf(td->loc2d[1] * size[1]) / size[1];
}
}
+ }
}
bool clipUVTransform(TransInfo *t, float vec[2], const bool resize)
{
- TransData *td;
- int a;
bool clipx = true, clipy = true;
float min[2], max[2];
@@ -3127,22 +3218,27 @@ bool clipUVTransform(TransInfo *t, float vec[2], const bool resize)
max[0] = t->aspect[0];
max[1] = t->aspect[1];
- for (a = 0, td = t->data; a < t->total; a++, td++) {
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+
+ TransData *td;
+ int a;
+
+ for (a = 0, td = tc->data; a < tc->data_len; a++, td++) {
minmax_v2v2_v2(min, max, td->loc);
}
if (resize) {
- if (min[0] < 0.0f && t->center[0] > 0.0f && t->center[0] < t->aspect[0] * 0.5f)
- vec[0] *= t->center[0] / (t->center[0] - min[0]);
- else if (max[0] > t->aspect[0] && t->center[0] < t->aspect[0])
- vec[0] *= (t->center[0] - t->aspect[0]) / (t->center[0] - max[0]);
+ if (min[0] < 0.0f && t->center_global[0] > 0.0f && t->center_global[0] < t->aspect[0] * 0.5f)
+ vec[0] *= t->center_global[0] / (t->center_global[0] - min[0]);
+ else if (max[0] > t->aspect[0] && t->center_global[0] < t->aspect[0])
+ vec[0] *= (t->center_global[0] - t->aspect[0]) / (t->center_global[0] - max[0]);
else
clipx = 0;
- if (min[1] < 0.0f && t->center[1] > 0.0f && t->center[1] < t->aspect[1] * 0.5f)
- vec[1] *= t->center[1] / (t->center[1] - min[1]);
- else if (max[1] > t->aspect[1] && t->center[1] < t->aspect[1])
- vec[1] *= (t->center[1] - t->aspect[1]) / (t->center[1] - max[1]);
+ if (min[1] < 0.0f && t->center_global[1] > 0.0f && t->center_global[1] < t->aspect[1] * 0.5f)
+ vec[1] *= t->center_global[1] / (t->center_global[1] - min[1]);
+ else if (max[1] > t->aspect[1] && t->center_global[1] < t->aspect[1])
+ vec[1] *= (t->center_global[1] - t->aspect[1]) / (t->center_global[1] - max[1]);
else
clipy = 0;
}
@@ -3161,16 +3257,16 @@ bool clipUVTransform(TransInfo *t, float vec[2], const bool resize)
else
clipy = 0;
}
+ }
return (clipx || clipy);
}
void clipUVData(TransInfo *t)
{
- TransData *td = NULL;
- int a;
-
- for (a = 0, td = t->data; a < t->total; a++, td++) {
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ TransData *td = tc->data;
+ for (int a = 0; a < tc->data_len; a++, td++) {
if (td->flag & TD_NOACTION)
break;
@@ -3180,6 +3276,7 @@ void clipUVData(TransInfo *t)
td->loc[0] = min_ff(max_ff(0.0f, td->loc[0]), t->aspect[0]);
td->loc[1] = min_ff(max_ff(0.0f, td->loc[1]), t->aspect[1]);
}
+ }
}
/* ********************* ANIMATION EDITORS (GENERAL) ************************* */
@@ -3212,7 +3309,9 @@ static void createTransNlaData(bContext *C, TransInfo *t)
int filter;
int count = 0;
-
+
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
/* determine what type of data we are operating on */
if (ANIM_animdata_get_context(C, &ac) == 0)
return;
@@ -3272,12 +3371,12 @@ static void createTransNlaData(bContext *C, TransInfo *t)
}
/* allocate memory for data */
- t->total = count;
+ tc->data_len = count;
- t->data = MEM_callocN(t->total * sizeof(TransData), "TransData(NLA Editor)");
- td = t->data;
- t->custom.type.data = tdn = MEM_callocN(t->total * sizeof(TransDataNla), "TransDataNla (NLA Editor)");
- t->custom.type.use_free = true;
+ tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransData(NLA Editor)");
+ td = tc->data;
+ tc->custom.type.data = tdn = MEM_callocN(tc->data_len * sizeof(TransDataNla), "TransDataNla (NLA Editor)");
+ tc->custom.type.use_free = true;
/* loop 2: build transdata array */
for (ale = anim_data.first; ale; ale = ale->next) {
@@ -3807,11 +3906,11 @@ typedef struct tGPFtransdata {
/* This function helps flush transdata written to tempdata into the gp-frames */
void flushTransIntFrameActionData(TransInfo *t)
{
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
tGPFtransdata *tfd = t->custom.type.data;
- int i;
/* flush data! */
- for (i = 0; i < t->total; i++, tfd++) {
+ for (int i = 0; i < tc->data_len; i++, tfd++) {
*(tfd->sdata) = round_fl_to_int(tfd->val);
}
}
@@ -3967,18 +4066,20 @@ static void createTransActionData(bContext *C, TransInfo *t)
ANIM_animdata_freelist(&anim_data);
return;
}
-
+
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
/* allocate memory for data */
- t->total = count;
+ tc->data_len = count;
- t->data = MEM_callocN(t->total * sizeof(TransData), "TransData(Action Editor)");
- t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "transdata2d");
- td = t->data;
- td2d = t->data2d;
+ tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransData(Action Editor)");
+ tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "transdata2d");
+ td = tc->data;
+ td2d = tc->data_2d;
if (ELEM(ac.datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK)) {
- t->custom.type.data = tfd = MEM_callocN(sizeof(tGPFtransdata) * count, "tGPFtransdata");
- t->custom.type.use_free = true;
+ tc->custom.type.data = tfd = MEM_callocN(sizeof(tGPFtransdata) * count, "tGPFtransdata");
+ tc->custom.type.use_free = true;
}
/* loop 2: build transdata array */
@@ -4023,7 +4124,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
/* calculate distances for proportional editing */
if (is_prop_edit) {
- td = t->data;
+ td = tc->data;
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt;
@@ -4365,19 +4466,21 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
ANIM_animdata_freelist(&anim_data);
return;
}
-
+
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
/* allocate memory for data */
- t->total = count;
+ tc->data_len = count;
- t->data = MEM_callocN(t->total * sizeof(TransData), "TransData (Graph Editor)");
+ tc->data = MEM_callocN(tc->data_len * 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->custom.type.data = MEM_callocN(t->total * sizeof(TransDataGraph), "TransDataGraph");
- t->custom.type.use_free = true;
+ tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransData2D (Graph Editor)");
+ tc->custom.type.data = MEM_callocN(tc->data_len * sizeof(TransDataGraph), "TransDataGraph");
+ tc->custom.type.use_free = true;
- td = t->data;
- td2d = t->data2d;
- tdg = t->custom.type.data;
+ td = tc->data;
+ td2d = tc->data_2d;
+ tdg = tc->custom.type.data;
/* precompute space-conversion matrices for dealing with non-uniform scaling of Graph Editor */
unit_m3(mtx);
@@ -4504,7 +4607,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
if (is_prop_edit) {
/* loop 2: build transdata arrays */
- td = t->data;
+ td = tc->data;
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
@@ -4660,12 +4763,14 @@ static void beztmap_to_data(TransInfo *t, FCurve *fcu, BeztMap *bezms, int totve
TransData *td;
int i, j;
char *adjusted;
-
+
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
/* dynamically allocate an array of chars to mark whether an TransData's
* pointers have been fixed already, so that we don't override ones that are
* already done
*/
- adjusted = MEM_callocN(t->total, "beztmap_adjusted_map");
+ adjusted = MEM_callocN(tc->data_len, "beztmap_adjusted_map");
/* for each beztmap item, find if it is used anywhere */
bezm = bezms;
@@ -4673,9 +4778,9 @@ static void beztmap_to_data(TransInfo *t, FCurve *fcu, BeztMap *bezms, int totve
/* loop through transdata, testing if we have a hit
* for the handles (vec[0]/vec[2]), we must also check if they need to be swapped...
*/
- td2d = t->data2d;
- td = t->data;
- for (j = 0; j < t->total; j++, td2d++, td++) {
+ td2d = tc->data_2d;
+ td = tc->data;
+ for (j = 0; j < tc->data_len; j++, td2d++, td++) {
/* skip item if already marked */
if (adjusted[j] != 0) continue;
@@ -4778,9 +4883,11 @@ void flushTransGraphData(TransInfo *t)
double secf = FPS;
int a;
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
/* flush to 2d vector from internally used 3d vector */
- for (a = 0, td = t->data, td2d = t->data2d, tdg = t->custom.type.data;
- a < t->total;
+ for (a = 0, td = tc->data, td2d = tc->data_2d, tdg = tc->custom.type.data;
+ a < tc->data_len;
a++, td++, td2d++, tdg++)
{
AnimData *adt = (AnimData *)td->extra; /* pointers to relevant AnimData blocks are stored in the td->extra pointers */
@@ -5142,13 +5249,15 @@ static void SeqTransDataBounds(TransInfo *t, ListBase *seqbase, TransSeq *ts)
}
-static void freeSeqData(TransInfo *t, TransCustomData *custom_data)
+static void freeSeqData(TransInfo *t, TransDataContainer *tc, TransCustomData *custom_data)
{
Editing *ed = BKE_sequencer_editing_get(t->scene, false);
if (ed != NULL) {
+
+
ListBase *seqbasep = ed->seqbasep;
- TransData *td = t->data;
+ TransData *td = tc->data;
int a;
/* prevent updating the same seq twice
@@ -5176,7 +5285,7 @@ static void freeSeqData(TransInfo *t, TransCustomData *custom_data)
{
int overlap = 0;
- for (a = 0, seq_prev = NULL; a < t->total; a++, td++, seq_prev = seq) {
+ for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
seq = ((TransDataSeq *)td->extra)->seq;
if ((seq != seq_prev) && (seq->depth == 0) && (seq->flag & SEQ_OVERLAP)) {
overlap = 1;
@@ -5189,8 +5298,8 @@ static void freeSeqData(TransInfo *t, TransCustomData *custom_data)
for (seq = seqbasep->first; seq; seq = seq->next)
seq->tmp = NULL;
- td = t->data;
- for (a = 0, seq_prev = NULL; a < t->total; a++, td++, seq_prev = seq) {
+ td = tc->data;
+ for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
seq = ((TransDataSeq *)td->extra)->seq;
if ((seq != seq_prev)) {
/* check effects strips, we cant change their time */
@@ -5213,8 +5322,8 @@ static void freeSeqData(TransInfo *t, TransCustomData *custom_data)
if (t->flag & T_ALT_TRANSFORM) {
int minframe = MAXFRAME;
- td = t->data;
- for (a = 0, seq_prev = NULL; a < t->total; a++, td++, seq_prev = seq) {
+ td = tc->data;
+ for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
seq = ((TransDataSeq *)td->extra)->seq;
if ((seq != seq_prev) && (seq->depth == 0)) {
minframe = min_ii(minframe, seq->startdisp);
@@ -5250,8 +5359,8 @@ static void freeSeqData(TransInfo *t, TransCustomData *custom_data)
if (has_effect_any) {
/* update effects strips based on strips just moved in time */
- td = t->data;
- for (a = 0, seq_prev = NULL; a < t->total; a++, td++, seq_prev = seq) {
+ td = tc->data;
+ for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
seq = ((TransDataSeq *)td->extra)->seq;
if ((seq != seq_prev)) {
if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
@@ -5263,8 +5372,8 @@ static void freeSeqData(TransInfo *t, TransCustomData *custom_data)
if (has_effect_root) {
/* now if any effects _still_ overlap, we need to move them up */
- td = t->data;
- for (a = 0, seq_prev = NULL; a < t->total; a++, td++, seq_prev = seq) {
+ td = tc->data;
+ for (a = 0, seq_prev = NULL; a < tc->data_len; a++, td++, seq_prev = seq) {
seq = ((TransDataSeq *)td->extra)->seq;
if ((seq != seq_prev) && (seq->depth == 0)) {
if ((seq->type & SEQ_TYPE_EFFECT) && seq->seq1) {
@@ -5293,7 +5402,7 @@ static void freeSeqData(TransInfo *t, TransCustomData *custom_data)
}
else {
/* Canceled, need to update the strips display */
- for (a = 0; a < t->total; a++, td++) {
+ for (a = 0; a < tc->data_len; a++, td++) {
seq = ((TransDataSeq *)td->extra)->seq;
if ((seq != seq_prev) && (seq->depth == 0)) {
if (seq->flag & SEQ_OVERLAP)
@@ -5312,9 +5421,9 @@ static void freeSeqData(TransInfo *t, TransCustomData *custom_data)
MEM_freeN(custom_data->data);
custom_data->data = NULL;
}
- if (t->data) {
- MEM_freeN(t->data); // XXX postTrans usually does this
- t->data = NULL;
+ if (tc->data) {
+ MEM_freeN(tc->data); // XXX postTrans usually does this
+ tc->data = NULL;
}
}
@@ -5333,12 +5442,14 @@ static void createTransSeqData(bContext *C, TransInfo *t)
int count = 0;
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
if (ed == NULL) {
- t->total = 0;
+ tc->data_len = 0;
return;
}
- t->custom.type.free_cb = freeSeqData;
+ tc->custom.type.free_cb = freeSeqData;
xmouse = (int)UI_view2d_region_to_view_x(v2d, t->mouse.imval[0]);
@@ -5377,18 +5488,18 @@ static void createTransSeqData(bContext *C, TransInfo *t)
count = SeqTransCount(t, NULL, ed->seqbasep, 0);
/* allocate memory for data */
- t->total = count;
+ tc->data_len = count;
/* stop if trying to build list if nothing selected */
if (count == 0) {
return;
}
- t->custom.type.data = ts = MEM_callocN(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");
+ tc->custom.type.data = ts = MEM_callocN(sizeof(TransSeq), "transseq");
+ tc->custom.type.use_free = true;
+ td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransSeq TransData");
+ td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransSeq TransData2D");
+ ts->tdseq = tdsq = MEM_callocN(tc->data_len * sizeof(TransDataSeq), "TransSeq TransDataSeq");
/* loop 2: build transdata array */
SeqToTransData_Recursive(t, ed->seqbasep, td, td2d, tdsq);
@@ -6118,9 +6229,11 @@ static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t)
{
/* so automerge supports mirror */
if ((t->scene->toolsettings->automerge) &&
- (t->obedit && t->obedit->type == OB_MESH))
+ ((t->flag & T_EDIT) && t->obedit_type == OB_MESH))
{
- BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
BMesh *bm = em->bm;
char hflag;
bool has_face_sel = (bm->totfacesel != 0);
@@ -6133,7 +6246,7 @@ static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t)
* tag all mirrored verts, then automerge those */
BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
- for (i = 0, td = t->data; i < t->total; i++, td++) {
+ for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
if (td->extra) {
BM_elem_flag_enable((BMVert *)td->extra, BM_ELEM_TAG);
}
@@ -6145,7 +6258,7 @@ static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t)
hflag = BM_ELEM_SELECT;
}
- EDBM_automerge(t->scene, t->obedit, true, hflag);
+ EDBM_automerge(t->scene, tc->obedit, true, hflag);
/* Special case, this is needed or faces won't re-select.
* Flush selected edges to faces. */
@@ -6153,6 +6266,7 @@ static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t)
EDBM_selectmode_flush_ex(em, SCE_SELECT_EDGE);
}
}
+ }
}
/* inserting keys, pointcache, redraw events... */
@@ -6168,50 +6282,53 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
const bool duplicate = (t->mode == TFM_TIME_DUPLICATE);
/* early out when nothing happened */
- if (t->total == 0 || t->mode == TFM_DUMMY)
+ if (t->data_len_all == 0 || t->mode == TFM_DUMMY) {
return;
-
+ }
+
if (t->spacetype == SPACE_VIEW3D) {
- if (t->obedit) {
+ if (t->flag & T_EDIT) {
/* 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->custom.mode.data;
-
/* handle multires re-projection, done
* on transform completion since it's
* really slow -joeedh */
projectEdgeSlideData(t, true);
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ EdgeSlideData *sld = tc->custom.mode.data;
+
/* free temporary faces to avoid automerging and deleting
* during cleanup - psy-fi */
freeEdgeSlideTempFaces(sld);
+ }
}
else if (t->mode == TFM_VERT_SLIDE) {
/* as above */
- VertSlideData *sld = t->custom.mode.data;
projectVertSlideData(t, true);
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ VertSlideData *sld = tc->custom.mode.data;
freeVertSlideTempFaces(sld);
+ }
}
- if (t->obedit->type == OB_MESH) {
+ if (t->obedit_type == OB_MESH) {
special_aftertrans_update__mesh(C, t);
}
}
else {
if (t->mode == TFM_EDGE_SLIDE) {
- EdgeSlideData *sld = t->custom.mode.data;
-
- sld->perc = 0.0;
+ EdgeSlideParams *slp = t->custom.mode.data;
+ slp->perc = 0.0;
projectEdgeSlideData(t, false);
}
else if (t->mode == TFM_VERT_SLIDE) {
- VertSlideData *sld = t->custom.mode.data;
-
- sld->perc = 0.0;
+ EdgeSlideParams *slp = t->custom.mode.data;
+ slp->perc = 0.0;
projectVertSlideData(t, false);
}
}
@@ -6485,26 +6602,33 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
ED_nla_postop_refresh(&ac);
}
}
- else if (t->obedit) {
- if (t->obedit->type == OB_MESH) {
- BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
- /* table needs to be created for each edit command, since vertices can move etc */
- ED_mesh_mirror_spatial_table(t->obedit, em, NULL, NULL, 'e');
+ else if (t->flag & T_EDIT) {
+ if (t->obedit_type == OB_MESH) {
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
+ /* table needs to be created for each edit command, since vertices can move etc */
+ ED_mesh_mirror_spatial_table(tc->obedit, em, NULL, NULL, 'e');
+ /* TODO(campbell): xform: We need support for many mirror objects at once! */
+ break;
+ }
}
}
- else if ((t->flag & T_POSE) && (t->poseobj)) {
+ else if (t->flag & T_POSE) {
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+
bArmature *arm;
bPoseChannel *pchan;
short targetless_ik = 0;
- ob = t->poseobj;
+ ob = tc->poseobj;
arm = ob->data;
if ((t->flag & T_AUTOIK) && (t->options & CTX_AUTOCONFIRM)) {
/* when running transform non-interactively (operator exec),
* we need to update the pose otherwise no updates get called during
* transform and the auto-ik is not applied. see [#26164] */
- struct Object *pose_ob = t->poseobj;
+ struct Object *pose_ob = tc->poseobj;
BKE_pose_where_is(&t->eval_ctx, t->scene, pose_ob);
}
@@ -6542,7 +6666,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
else {
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
-
+ }
}
else if (t->options & CTX_PAINT_CURVE) {
/* pass */
@@ -6559,8 +6683,10 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
BLI_assert(t->flag & (T_OBJECT | T_TEXTURE));
- for (i = 0; i < t->total; i++) {
- TransData *td = t->data + i;
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
+ for (i = 0; i < tc->data_len; i++) {
+ TransData *td = tc->data + i;
ListBase pidlist;
PTCacheID *pid;
ob = td->ob;
@@ -6614,7 +6740,7 @@ int special_transform_moving(TransInfo *t)
else if (t->spacetype == SPACE_IPO) {
return G_TRANSFORM_FCURVES;
}
- else if (t->obedit || ((t->flag & T_POSE) && (t->poseobj))) {
+ else if ((t->flag & T_EDIT) || (t->flag & T_POSE)) {
return G_TRANSFORM_EDIT;
}
else if (t->flag & (T_OBJECT | T_TEXTURE)) {
@@ -6632,21 +6758,23 @@ static void createTransObject(bContext *C, TransInfo *t)
set_trans_object_base_flags(t);
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
/* count */
- t->total = CTX_DATA_COUNT(C, selected_objects);
+ tc->data_len = CTX_DATA_COUNT(C, selected_objects);
- if (!t->total) {
+ if (!tc->data_len) {
/* clear here, main transform function escapes too */
clear_trans_object_base_flags(t);
return;
}
if (is_prop_edit) {
- t->total += count_proportional_objects(t);
+ tc->data_len += count_proportional_objects(t);
}
- td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransOb");
- tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "TransObExtension");
+ td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransOb");
+ tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "TransObExtension");
CTX_DATA_BEGIN(C, Base *, base, selected_bases)
{
@@ -6766,7 +6894,9 @@ static void createTransNodeData(bContext *UNUSED(C), TransInfo *t)
SpaceNode *snode = t->sa->spacedata.first;
bNode *node;
- t->total = 0;
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
+ tc->data_len = 0;
if (!snode->edittree) {
return;
@@ -6779,15 +6909,15 @@ static void createTransNodeData(bContext *UNUSED(C), TransInfo *t)
for (node = snode->edittree->nodes.first; node; node = node->next) {
if (node->flag & NODE_SELECT && is_node_parent_select(node) == false) {
node->flag |= NODE_TRANSFORM;
- t->total++;
+ tc->data_len++;
}
else {
node->flag &= ~NODE_TRANSFORM;
}
}
- td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransNode TransData");
- td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransNode TransData2D");
+ td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransNode TransData");
+ td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransNode TransData2D");
for (node = snode->edittree->nodes.first; node; node = node->next) {
if (node->flag & NODE_TRANSFORM) {
@@ -6972,7 +7102,7 @@ static void planeTrackToTransData(const int framenr, TransData *td, TransData2D
}
}
-static void transDataTrackingFree(TransInfo *UNUSED(t), TransCustomData *custom_data)
+static void transDataTrackingFree(TransInfo *UNUSED(t), TransDataContainer *UNUSED(tc), TransCustomData *custom_data)
{
if (custom_data->data) {
TransDataTracking *tdt = custom_data->data;
@@ -6997,22 +7127,24 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
TransDataTracking *tdt;
int framenr = ED_space_clip_get_clip_frame_number(sc);
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
/* count */
- t->total = 0;
+ tc->data_len = 0;
track = tracksbase->first;
while (track) {
if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
- t->total++; /* offset */
+ tc->data_len++; /* offset */
if (track->flag & SELECT)
- t->total++;
+ tc->data_len++;
if (track->pat_flag & SELECT)
- t->total += 4;
+ tc->data_len += 4;
if (track->search_flag & SELECT)
- t->total += 2;
+ tc->data_len += 2;
}
track = track->next;
@@ -7023,18 +7155,18 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
plane_track = plane_track->next)
{
if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
- t->total += 4;
+ tc->data_len += 4;
}
}
- if (t->total == 0)
+ if (tc->data_len == 0)
return;
- td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransTracking TransData");
- td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransTracking TransData2D");
- tdt = t->custom.type.data = MEM_callocN(t->total * sizeof(TransDataTracking), "TransTracking TransDataTracking");
+ td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransTracking TransData");
+ td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransTracking TransData2D");
+ tdt = tc->custom.type.data = MEM_callocN(tc->data_len * sizeof(TransDataTracking), "TransTracking TransDataTracking");
- t->custom.type.free_cb = transDataTrackingFree;
+ tc->custom.type.free_cb = transDataTrackingFree;
/* create actual data */
track = tracksbase->first;
@@ -7136,8 +7268,10 @@ static void createTransTrackingCurvesData(bContext *C, TransInfo *t)
BKE_movieclip_get_size(clip, &sc->user, &width, &height);
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
/* count */
- t->total = 0;
+ tc->data_len = 0;
if ((sc->flag & SC_SHOW_GRAPH_TRACKS_MOTION) == 0) {
return;
@@ -7154,23 +7288,23 @@ static void createTransTrackingCurvesData(bContext *C, TransInfo *t)
continue;
if (marker->flag & MARKER_GRAPH_SEL_X)
- t->total += 1;
+ tc->data_len += 1;
if (marker->flag & MARKER_GRAPH_SEL_Y)
- t->total += 1;
+ tc->data_len += 1;
}
}
track = track->next;
}
- if (t->total == 0)
+ if (tc->data_len == 0)
return;
- td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransTracking TransData");
- td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransTracking TransData2D");
- t->custom.type.data = tdt = MEM_callocN(t->total * sizeof(TransDataTracking), "TransTracking TransDataTracking");
- t->custom.type.free_cb = transDataTrackingFree;
+ td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransTracking TransData");
+ td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransTracking TransData2D");
+ tc->custom.type.data = tdt = MEM_callocN(tc->data_len * sizeof(TransDataTracking), "TransTracking TransDataTracking");
+ tc->custom.type.free_cb = transDataTrackingFree;
/* create actual data */
track = tracksbase->first;
@@ -7211,7 +7345,9 @@ static void createTransTrackingData(bContext *C, TransInfo *t)
MovieClip *clip = ED_space_clip_get_clip(sc);
int width, height;
- t->total = 0;
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
+ tc->data_len = 0;
if (!clip)
return;
@@ -7232,12 +7368,14 @@ static void createTransTrackingData(bContext *C, TransInfo *t)
static void cancelTransTracking(TransInfo *t)
{
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(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;
+ TransDataTracking *tdt_array = tc->custom.type.data;
+
i = 0;
- while (i < t->total) {
+ while (i < tc->data_len) {
TransDataTracking *tdt = &tdt_array[i];
if (tdt->mode == transDataTracking_ModeTracks) {
@@ -7294,8 +7432,10 @@ void flushTransTracking(TransInfo *t)
if (t->state == TRANS_CANCEL)
cancelTransTracking(t);
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
/* flush to 2d vector from internally used 3d vector */
- for (a = 0, td = t->data, td2d = t->data2d, tdt = t->custom.type.data; a < t->total; a++, td2d++, td++, tdt++) {
+ for (a = 0, td = tc->data, td2d = tc->data_2d, tdt = tc->custom.type.data; a < tc->data_len; a++, td2d++, td++, tdt++) {
if (tdt->mode == transDataTracking_ModeTracks) {
float loc2d[2];
@@ -7561,7 +7701,9 @@ static void createTransMaskingData(bContext *C, TransInfo *t)
const bool is_prop_edit = (t->flag & T_PROP_EDIT);
float asp[2];
- t->total = 0;
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
+ tc->data_len = 0;
if (!mask)
return;
@@ -7621,13 +7763,13 @@ static void createTransMaskingData(bContext *C, TransInfo *t)
ED_mask_get_aspect(t->sa, t->ar, &asp[0], &asp[1]);
- t->total = (is_prop_edit) ? count : countsel;
- td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Mask Editing)");
+ tc->data_len = (is_prop_edit) ? count : countsel;
+ td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Mask Editing)");
/* 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)");
- t->custom.type.data = tdm = MEM_callocN(t->total * sizeof(TransDataMasking), "TransDataMasking(Mask Editing)");
- t->custom.type.use_free = true;
+ td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransObData2D(Mask Editing)");
+ tc->custom.type.data = tdm = MEM_callocN(tc->data_len * sizeof(TransDataMasking), "TransDataMasking(Mask Editing)");
+ tc->custom.type.use_free = true;
/* create data */
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
@@ -7684,12 +7826,14 @@ void flushTransMasking(TransInfo *t)
int a;
float asp[2], inv[2];
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
ED_mask_get_aspect(t->sa, t->ar, &asp[0], &asp[1]);
inv[0] = 1.0f / asp[0];
inv[1] = 1.0f / asp[1];
/* flush to 2d vector from internally used 3d vector */
- for (a = 0, td = t->data2d, tdm = t->custom.type.data; a < t->total; a++, td++, tdm++) {
+ for (a = 0, td = tc->data_2d, tdm = tc->custom.type.data; a < tc->data_len; 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);
@@ -7808,7 +7952,9 @@ static void createTransPaintCurveVerts(bContext *C, TransInfo *t)
int i;
int total = 0;
- t->total = 0;
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
+ tc->data_len = 0;
if (!paint || !paint->brush || !paint->brush->paint_curve)
return;
@@ -7834,11 +7980,11 @@ static void createTransPaintCurveVerts(bContext *C, TransInfo *t)
if (!total)
return;
- t->total = total;
- td2d = t->data2d = MEM_callocN(t->total * sizeof(TransData2D), "TransData2D");
- td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransData");
- t->custom.type.data = tdpc = MEM_callocN(t->total * sizeof(TransDataPaintCurve), "TransDataPaintCurve");
- t->custom.type.use_free = true;
+ tc->data_len = total;
+ td2d = tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransData2D");
+ td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransData");
+ tc->custom.type.data = tdpc = MEM_callocN(tc->data_len * sizeof(TransDataPaintCurve), "TransDataPaintCurve");
+ tc->custom.type.use_free = true;
for (pcp = pc->points, i = 0; i < pc->tot_points; i++, pcp++) {
if (PC_IS_ANY_SEL(pcp)) {
@@ -7869,10 +8015,13 @@ static void createTransPaintCurveVerts(bContext *C, TransInfo *t)
void flushTransPaintCurve(TransInfo *t)
{
int i;
- TransData2D *td2d = t->data2d;
- TransDataPaintCurve *tdpc = t->custom.type.data;
- for (i = 0; i < t->total; i++, tdpc++, td2d++) {
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
+ TransData2D *td2d = tc->data_2d;
+ TransDataPaintCurve *tdpc = tc->custom.type.data;
+
+ for (i = 0; i < tc->data_len; i++, tdpc++, td2d++) {
PaintCurvePoint *pcp = tdpc->pcp;
copy_v2_v2(pcp->bez.vec[tdpc->id], td2d->loc);
}
@@ -7891,15 +8040,16 @@ static void createTransGPencil(bContext *C, TransInfo *t)
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
const bool is_prop_edit_connected = (t->flag & T_PROP_CONNECTED) != 0;
-
-
+
+ TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
+
/* == Grease Pencil Strokes to Transform Data ==
* Grease Pencil stroke points can be a mixture of 2D (screen-space),
* or 3D coordinates. However, they're always saved as 3D points.
* For now, we just do these without creating TransData2D for the 2D
* strokes. This may cause issues in future though.
*/
- t->total = 0;
+ tc->data_len = 0;
if (gpd == NULL)
return;
@@ -7928,11 +8078,11 @@ static void createTransGPencil(bContext *C, TransInfo *t)
if (is_prop_edit_connected) {
/* connected only - so only if selected */
if (gps->flag & GP_STROKE_SELECT)
- t->total += gps->totpoints;
+ tc->data_len += gps->totpoints;
}
else {
/* everything goes - connection status doesn't matter */
- t->total += gps->totpoints;
+ tc->data_len += gps->totpoints;
}
}
else {
@@ -7944,7 +8094,7 @@ static void createTransGPencil(bContext *C, TransInfo *t)
// TODO: 2D vs 3D?
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
if (pt->flag & GP_SPOINT_SELECT)
- t->total++;
+ tc->data_len++;
}
}
}
@@ -7953,13 +8103,13 @@ static void createTransGPencil(bContext *C, TransInfo *t)
}
/* Stop trying if nothing selected */
- if (t->total == 0) {
+ if (tc->data_len == 0) {
return;
}
/* Allocate memory for data */
- t->data = MEM_callocN(t->total * sizeof(TransData), "TransData(GPencil)");
- td = t->data;
+ tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransData(GPencil)");
+ td = tc->data;
unit_m3(smtx);
unit_m3(mtx);
@@ -8127,6 +8277,29 @@ static void createTransGPencil(bContext *C, TransInfo *t)
}
}
+static int countAndCleanTransDataContainer(TransInfo *t)
+{
+ BLI_assert(ELEM(t->data_len_all, 0, -1));
+ t->data_len_all = 0;
+ uint data_container_len_orig = t->data_container_len;
+ for (TransDataContainer *th_end = t->data_container - 1, *tc = t->data_container + (t->data_container_len - 1); tc != th_end; tc--) {
+ if (tc->data_len == 0) {
+ uint index = tc - t->data_container;
+ if (index + 1 != t->data_container_len) {
+ SWAP(TransDataContainer, t->data_container[index], t->data_container[t->data_container_len - 1]);
+ }
+ t->data_container_len -= 1;
+ }
+ else {
+ t->data_len_all += tc->data_len;
+ }
+ }
+ if (data_container_len_orig != t->data_container_len) {
+ t->data_container = MEM_reallocN(t->data_container, sizeof(*t->data_container) * t->data_container_len);
+ }
+ return t->data_len_all;
+}
+
void createTransData(bContext *C, TransInfo *t)
{
@@ -8134,16 +8307,27 @@ void createTransData(bContext *C, TransInfo *t)
ViewLayer *view_layer = t->view_layer;
Object *ob = OBACT(view_layer);
+ t->data_len_all = -1;
+
/* if tests must match recalcData for correct updates */
if (t->options & CTX_TEXTURE) {
t->flag |= T_TEXTURE;
+
createTransTexspace(t);
+ countAndCleanTransDataContainer(t);
}
else if (t->options & CTX_EDGE) {
- t->ext = NULL;
+ /* Multi object editing. */
+ initTransDataContainers_FromObjectData(t);
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ tc->data_ext = NULL;
+ }
t->flag |= T_EDIT;
+
createTransEdge(t);
- if (t->data && t->flag & T_PROP_EDIT) {
+ countAndCleanTransDataContainer(t);
+
+ if (t->data_len_all && t->flag & T_PROP_EDIT) {
sort_trans_data(t); // makes selected become first in array
set_prop_dist(t, 1);
sort_trans_data_dist(t);
@@ -8152,9 +8336,11 @@ void createTransData(bContext *C, TransInfo *t)
else if (t->options & CTX_GPENCIL_STROKES) {
t->options |= CTX_GPENCIL_STROKES;
t->flag |= T_POINTS;
+
createTransGPencil(C, t);
+ countAndCleanTransDataContainer(t);
- if (t->data && (t->flag & T_PROP_EDIT)) {
+ if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
sort_trans_data(t); // makes selected become first in array
set_prop_dist(t, 1);
sort_trans_data_dist(t);
@@ -8163,22 +8349,32 @@ void createTransData(bContext *C, TransInfo *t)
else if (t->spacetype == SPACE_IMAGE) {
t->flag |= T_POINTS | T_2D_EDIT;
if (t->options & CTX_MASK) {
+
/* copied from below */
createTransMaskingData(C, t);
+ countAndCleanTransDataContainer(t);
- if (t->data && (t->flag & T_PROP_EDIT)) {
+ if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
sort_trans_data(t); // makes selected become first in array
set_prop_dist(t, true);
sort_trans_data_dist(t);
}
}
else if (t->options & CTX_PAINT_CURVE) {
- if (!ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN))
+ if (!ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) {
createTransPaintCurveVerts(C, t);
+ countAndCleanTransDataContainer(t);
+ }
}
- else if (t->obedit) {
+ else if (t->obedit_type == OB_MESH) {
+
+ initTransDataContainers_FromObjectData(t);
createTransUVs(C, t);
- if (t->data && (t->flag & T_PROP_EDIT)) {
+ countAndCleanTransDataContainer(t);
+
+ t->flag |= T_EDIT;
+
+ if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
sort_trans_data(t); // makes selected become first in array
set_prop_dist(t, 1);
sort_trans_data_dist(t);
@@ -8187,9 +8383,11 @@ void createTransData(bContext *C, TransInfo *t)
}
else if (t->spacetype == SPACE_ACTION) {
t->flag |= T_POINTS | T_2D_EDIT;
+
createTransActionData(C, t);
+ countAndCleanTransDataContainer(t);
- if (t->data && (t->flag & T_PROP_EDIT)) {
+ if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
sort_trans_data(t); // makes selected become first in array
//set_prop_dist(t, false); /* don't do that, distance has been set in createTransActionData already */
sort_trans_data_dist(t);
@@ -8198,17 +8396,20 @@ void createTransData(bContext *C, TransInfo *t)
else if (t->spacetype == SPACE_NLA) {
t->flag |= T_POINTS | T_2D_EDIT;
createTransNlaData(C, t);
+ countAndCleanTransDataContainer(t);
}
else if (t->spacetype == SPACE_SEQ) {
t->flag |= T_POINTS | T_2D_EDIT;
t->num.flag |= NUM_NO_FRACTION; /* sequencer has no use for floating point transformations */
createTransSeqData(C, t);
+ countAndCleanTransDataContainer(t);
}
else if (t->spacetype == SPACE_IPO) {
t->flag |= T_POINTS | T_2D_EDIT;
createTransGraphEditData(C, t);
+ countAndCleanTransDataContainer(t);
- if (t->data && (t->flag & T_PROP_EDIT)) {
+ if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
sort_trans_data(t); // makes selected become first in array
set_prop_dist(t, false); /* don't do that, distance has been set in createTransGraphEditData already */
sort_trans_data_dist(t);
@@ -8216,8 +8417,11 @@ void createTransData(bContext *C, TransInfo *t)
}
else if (t->spacetype == SPACE_NODE) {
t->flag |= T_POINTS | T_2D_EDIT;
+
createTransNodeData(C, t);
- if (t->data && (t->flag & T_PROP_EDIT)) {
+ countAndCleanTransDataContainer(t);
+
+ if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
sort_trans_data(t); // makes selected become first in array
set_prop_dist(t, 1);
sort_trans_data_dist(t);
@@ -8225,34 +8429,42 @@ void createTransData(bContext *C, TransInfo *t)
}
else if (t->spacetype == SPACE_CLIP) {
t->flag |= T_POINTS | T_2D_EDIT;
- if (t->options & CTX_MOVIECLIP)
+ if (t->options & CTX_MOVIECLIP) {
createTransTrackingData(C, t);
+ countAndCleanTransDataContainer(t);
+ }
else if (t->options & CTX_MASK) {
/* copied from above */
createTransMaskingData(C, t);
+ countAndCleanTransDataContainer(t);
- if (t->data && (t->flag & T_PROP_EDIT)) {
+ if (t->data_len_all && (t->flag & T_PROP_EDIT)) {
sort_trans_data(t); // makes selected become first in array
set_prop_dist(t, true);
sort_trans_data_dist(t);
}
}
}
- else if (t->obedit) {
- t->ext = NULL;
- if (t->obedit->type == OB_MESH) {
+ else if (t->obedit_type != -1) {
+ /* Multi object editing. */
+ initTransDataContainers_FromObjectData(t);
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ tc->data_ext = NULL;
+ }
+ if (t->obedit_type == OB_MESH) {
createTransEditVerts(t);
}
- else if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) {
+ else if (ELEM(t->obedit_type, OB_CURVE, OB_SURF)) {
createTransCurveVerts(t);
}
- else if (t->obedit->type == OB_LATTICE) {
+ else if (t->obedit_type == OB_LATTICE) {
createTransLatticeVerts(t);
}
- else if (t->obedit->type == OB_MBALL) {
+ else if (t->obedit_type == OB_MBALL) {
createTransMBallVerts(t);
}
- else if (t->obedit->type == OB_ARMATURE) {
+ else if (t->obedit_type == OB_ARMATURE) {
t->flag &= ~T_PROP_EDIT;
createTransArmatureVerts(t);
}
@@ -8260,12 +8472,14 @@ void createTransData(bContext *C, TransInfo *t)
printf("edit type not implemented!\n");
}
+ countAndCleanTransDataContainer(t);
+
t->flag |= T_EDIT | T_POINTS;
- if (t->data && t->flag & T_PROP_EDIT) {
- if (ELEM(t->obedit->type, OB_CURVE, OB_MESH)) {
+ if (t->data_len_all && t->flag & T_PROP_EDIT) {
+ if (ELEM(t->obedit_type, OB_CURVE, OB_MESH)) {
sort_trans_data(t); // makes selected become first in array
- if ((t->obedit->type == OB_MESH) && (t->flag & T_PROP_CONNECTED)) {
+ if ((t->obedit_type == OB_MESH) && (t->flag & T_PROP_CONNECTED)) {
/* already calculated by editmesh_set_connectivity_distance */
}
else {
@@ -8284,13 +8498,21 @@ void createTransData(bContext *C, TransInfo *t)
if (t->mode == TFM_BONESIZE) {
t->flag &= ~(T_EDIT | T_POINTS);
t->flag |= T_POSE;
- t->poseobj = ob; /* <- tsk tsk, this is going to give issues one day */
+
+ FOREACH_TRANS_DATA_CONTAINER (t, tc) {
+ tc->poseobj = tc->obedit;
+ tc->obedit = NULL;
+ }
}
}
else if (ob && (ob->mode & OB_MODE_POSE)) {
// XXX this is currently limited to active armature only...
// XXX active-layer checking isn't done as that should probably be checked through context instead
- createTransPose(t, ob);
+
+ /* Multi object editing. */
+ initTransDataContainers_FromObjectData(t);
+ createTransPose(t, NULL, 0);
+ countAndCleanTransDataContainer(t);
}
else if (ob && (ob->mode & OB_MODE_WEIGHT_PAINT) && !(t->options & CTX_PAINT_CURVE)) {
/* important that ob_armature can be set even when its not selected [#23412]
@@ -8300,7 +8522,11 @@ void createTransData(bContext *C, TransInfo *t)
Base *base_arm = BKE_view_layer_base_find(t->view_layer, ob_armature);
if (base_arm) {
if (BASE_VISIBLE(base_arm)) {
- createTransPose(t, ob_armature);
+ Object *objects[1];
+ objects[0] = ob_armature;
+ uint objects_len = 1;
+ createTransPose(t, objects, objects_len);
+ countAndCleanTransDataContainer(t);
}
}
@@ -8308,9 +8534,10 @@ void createTransData(bContext *C, TransInfo *t)
}
else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT) && PE_start_edit(PE_get_current(scene, ob))) {
createTransParticleVerts(C, t);
+ countAndCleanTransDataContainer(t);
t->flag |= T_POINTS;
- if (t->data && t->flag & T_PROP_EDIT) {
+ if (t->data_len_all && t->flag & T_PROP_EDIT) {
sort_trans_data(t); // makes selected become first in array
set_prop_dist(t, 1);
sort_trans_data_dist(t);
@@ -8320,13 +8547,15 @@ void createTransData(bContext *C, TransInfo *t)
if ((t->options & CTX_PAINT_CURVE) && !ELEM(t->mode, TFM_SHEAR, TFM_SHRINKFATTEN)) {
t->flag |= T_POINTS | T_2D_EDIT;
createTransPaintCurveVerts(C, t);
+ countAndCleanTransDataContainer(t);
}
}
else {
createTransObject(C, t);
+ countAndCleanTransDataContainer(t);
t->flag |= T_OBJECT;
- if (t->data && t->flag & T_PROP_EDIT) {
+ if (t->data_len_all && t->flag & T_PROP_EDIT) {
// selected objects are already first, no need to presort
set_prop_dist(t, 1);
sort_trans_data_dist(t);
@@ -8344,4 +8573,7 @@ void createTransData(bContext *C, TransInfo *t)
}
}
}
+
+ /* Check that 'countAndCleanTransDataContainer' ran. */
+ BLI_assert(t->data_len_all != -1);
}