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.c971
1 files changed, 655 insertions, 316 deletions
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index b50f56aae3e..c9e7e085a96 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -31,6 +31,7 @@
#include <string.h>
#include <math.h>
+#include <limits.h>
#include "DNA_anim_types.h"
#include "DNA_brush_types.h"
@@ -58,6 +59,7 @@
#include "BLI_linklist_stack.h"
#include "BLI_string.h"
#include "BLI_bitmap.h"
+#include "BLI_rect.h"
#include "BKE_DerivedMesh.h"
#include "BKE_action.h"
@@ -340,20 +342,20 @@ static void createTransEdge(TransInfo *t)
BMIter iter;
float mtx[3][3], smtx[3][3];
int count = 0, countsel = 0;
- int propmode = t->flag & T_PROP_EDIT;
+ const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
int cd_edge_float_offset;
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) countsel++;
- if (propmode) count++;
+ if (is_prop_edit) count++;
}
}
if (countsel == 0)
return;
- if (propmode) {
+ if (is_prop_edit) {
t->total = count;
}
else {
@@ -379,7 +381,7 @@ static void createTransEdge(TransInfo *t)
BLI_assert(cd_edge_float_offset != -1);
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
- if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || propmode)) {
+ if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || is_prop_edit)) {
float *fl_ptr;
/* need to set center for center calculations */
mid_v3_v3v3(td->center, eed->v1->co, eed->v2->co);
@@ -627,10 +629,10 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr
mul_m3_m3m3(td->axismtx, omat, pmat);
normalize_m3(td->axismtx);
- if (t->mode == TFM_BONESIZE) {
+ if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
bArmature *arm = t->poseobj->data;
- if (arm->drawtype == ARM_ENVELOPE) {
+ if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) {
td->loc = NULL;
td->val = &bone->dist;
td->ival = bone->dist;
@@ -717,7 +719,7 @@ int count_set_pose_transflags(int *out_mode, short around, Object *ob)
/* make sure no bone can be transformed when a parent is transformed */
/* since pchans are depsgraph sorted, the parents are in beginning of list */
- if (mode != TFM_BONESIZE) {
+ if (!ELEM(mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
bone = pchan->bone;
if (bone->flag & BONE_TRANSFORM)
@@ -1124,7 +1126,7 @@ static void createTransArmatureVerts(TransInfo *t)
oldtot = t->total;
if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) {
- if (t->mode == TFM_BONESIZE) {
+ if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
if (ebo->flag & BONE_SELECTED)
t->total++;
}
@@ -1202,9 +1204,9 @@ static void createTransArmatureVerts(TransInfo *t)
}
}
- else if (t->mode == TFM_BONESIZE) {
+ else if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
if (ebo->flag & BONE_SELECTED) {
- if (arm->drawtype == ARM_ENVELOPE) {
+ if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) {
td->loc = NULL;
td->val = &ebo->dist;
td->ival = ebo->dist;
@@ -1329,18 +1331,18 @@ static void createTransMBallVerts(TransInfo *t)
TransDataExtension *tx;
float mtx[3][3], smtx[3][3];
int count = 0, countsel = 0;
- int propmode = t->flag & T_PROP_EDIT;
+ const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
/* count totals */
for (ml = mb->editelems->first; ml; ml = ml->next) {
if (ml->flag & SELECT) countsel++;
- if (propmode) count++;
+ if (is_prop_edit) count++;
}
/* note: in prop mode we need at least 1 selected */
if (countsel == 0) return;
- if (propmode) t->total = count;
+ if (is_prop_edit) t->total = count;
else t->total = countsel;
td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(MBall EditMode)");
@@ -1350,7 +1352,7 @@ static void createTransMBallVerts(TransInfo *t)
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
for (ml = mb->editelems->first; ml; ml = ml->next) {
- if (propmode || (ml->flag & SELECT)) {
+ if (is_prop_edit || (ml->flag & SELECT)) {
td->loc = &ml->x;
copy_v3_v3(td->iloc, td->loc);
copy_v3_v3(td->center, td->loc);
@@ -1463,7 +1465,7 @@ static void createTransCurveVerts(TransInfo *t)
float mtx[3][3], smtx[3][3];
int a;
int count = 0, countsel = 0;
- int propmode = t->flag & T_PROP_EDIT;
+ const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
short hide_handles = (cu->drawflag & CU_HIDE_HANDLES);
ListBase *nurbs;
@@ -1478,13 +1480,13 @@ static void createTransCurveVerts(TransInfo *t)
if (bezt->hide == 0) {
if (hide_handles) {
if (bezt->f2 & SELECT) countsel += 3;
- if (propmode) count += 3;
+ if (is_prop_edit) count += 3;
}
else {
if (bezt->f1 & SELECT) countsel++;
if (bezt->f2 & SELECT) countsel++;
if (bezt->f3 & SELECT) countsel++;
- if (propmode) count += 3;
+ if (is_prop_edit) count += 3;
}
}
}
@@ -1492,7 +1494,7 @@ static void createTransCurveVerts(TransInfo *t)
else {
for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
if (bp->hide == 0) {
- if (propmode) count++;
+ if (is_prop_edit) count++;
if (bp->f1 & SELECT) countsel++;
}
}
@@ -1501,7 +1503,7 @@ static void createTransCurveVerts(TransInfo *t)
/* note: in prop mode we need at least 1 selected */
if (countsel == 0) return;
- if (propmode) t->total = count;
+ if (is_prop_edit) t->total = count;
else t->total = countsel;
t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Curve EditMode)");
@@ -1536,7 +1538,7 @@ static void createTransCurveVerts(TransInfo *t)
}
}
- if (propmode ||
+ if (is_prop_edit ||
((bezt->f2 & SELECT) && hide_handles) ||
((bezt->f1 & SELECT) && hide_handles == 0))
{
@@ -1570,7 +1572,7 @@ static void createTransCurveVerts(TransInfo *t)
}
/* This is the Curve Point, the other two are handles */
- if (propmode || (bezt->f2 & SELECT)) {
+ if (is_prop_edit || (bezt->f2 & SELECT)) {
copy_v3_v3(td->iloc, bezt->vec[1]);
td->loc = bezt->vec[1];
copy_v3_v3(td->center, td->loc);
@@ -1606,7 +1608,7 @@ static void createTransCurveVerts(TransInfo *t)
count++;
tail++;
}
- if (propmode ||
+ if (is_prop_edit ||
((bezt->f2 & SELECT) && hide_handles) ||
((bezt->f3 & SELECT) && hide_handles == 0))
{
@@ -1643,12 +1645,12 @@ static void createTransCurveVerts(TransInfo *t)
(void)hdata; /* quiet warning */
}
- else if (propmode && head != tail) {
+ else if (is_prop_edit && head != tail) {
calc_distanceCurveVerts(head, tail - 1);
head = tail;
}
}
- if (propmode && head != tail)
+ if (is_prop_edit && head != tail)
calc_distanceCurveVerts(head, tail - 1);
/* TODO - in the case of tilt and radius we can also avoid allocating the initTransDataCurveHandles
@@ -1663,7 +1665,7 @@ static void createTransCurveVerts(TransInfo *t)
head = tail = td;
for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
if (bp->hide == 0) {
- if (propmode || (bp->f1 & SELECT)) {
+ if (is_prop_edit || (bp->f1 & SELECT)) {
copy_v3_v3(td->iloc, bp->vec);
td->loc = bp->vec;
copy_v3_v3(td->center, td->loc);
@@ -1688,12 +1690,12 @@ static void createTransCurveVerts(TransInfo *t)
tail++;
}
}
- else if (propmode && head != tail) {
+ else if (is_prop_edit && head != tail) {
calc_distanceCurveVerts(head, tail - 1);
head = tail;
}
}
- if (propmode && head != tail)
+ if (is_prop_edit && head != tail)
calc_distanceCurveVerts(head, tail - 1);
}
}
@@ -1709,14 +1711,14 @@ static void createTransLatticeVerts(TransInfo *t)
float mtx[3][3], smtx[3][3];
int a;
int count = 0, countsel = 0;
- int propmode = t->flag & T_PROP_EDIT;
+ const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
bp = latt->def;
a = latt->pntsu * latt->pntsv * latt->pntsw;
while (a--) {
if (bp->hide == 0) {
if (bp->f1 & SELECT) countsel++;
- if (propmode) count++;
+ if (is_prop_edit) count++;
}
bp++;
}
@@ -1724,7 +1726,7 @@ static void createTransLatticeVerts(TransInfo *t)
/* note: in prop mode we need at least 1 selected */
if (countsel == 0) return;
- if (propmode) t->total = count;
+ if (is_prop_edit) t->total = count;
else t->total = countsel;
t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Lattice EditMode)");
@@ -1735,7 +1737,7 @@ static void createTransLatticeVerts(TransInfo *t)
bp = latt->def;
a = latt->pntsu * latt->pntsv * latt->pntsw;
while (a--) {
- if (propmode || (bp->f1 & SELECT)) {
+ if (is_prop_edit || (bp->f1 & SELECT)) {
if (bp->hide == 0) {
copy_v3_v3(td->iloc, bp->vec);
td->loc = bp->vec;
@@ -1776,7 +1778,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
float mat[4][4];
int i, k, transformparticle;
int count = 0, hasselected = 0;
- int propmode = t->flag & T_PROP_EDIT;
+ const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
if (edit == NULL || t->settings->particle.selectmode == SCE_SELECT_PATH) return;
@@ -1798,7 +1800,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
hasselected = 1;
transformparticle = 1;
}
- else if (propmode)
+ else if (is_prop_edit)
transformparticle = 1;
}
}
@@ -1848,7 +1850,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
if (key->flag & PEK_SELECT)
td->flag |= TD_SELECTED;
- else if (!propmode)
+ else if (!is_prop_edit)
td->flag |= TD_SKIP;
unit_m3(td->mtx);
@@ -1877,7 +1879,7 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
tx++;
tail++;
}
- if (propmode && head != tail)
+ if (is_prop_edit && head != tail)
calc_distanceCurveVerts(head, tail - 1);
}
}
@@ -1893,7 +1895,8 @@ void flushTransParticles(TransInfo *t)
PTCacheEditKey *key;
TransData *td;
float mat[4][4], imat[4][4], co[3];
- int i, k, propmode = t->flag & T_PROP_EDIT;
+ int i, k;
+ const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
if (psys)
psmd = psys_get_modifier(ob, psys);
@@ -1914,7 +1917,7 @@ void flushTransParticles(TransInfo *t)
/* optimization for proportional edit */
- if (!propmode || !compare_v3v3(key->co, co, 0.0001f)) {
+ if (!is_prop_edit || !compare_v3v3(key->co, co, 0.0001f)) {
copy_v3_v3(key->co, co);
point->flag |= PEP_EDIT_RECALC;
}
@@ -1972,17 +1975,19 @@ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float
int i;
BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
+ float dist;
BM_elem_index_set(v, i); /* set_inline */
BM_elem_flag_disable(v, BM_ELEM_TAG);
if (BM_elem_flag_test(v, BM_ELEM_SELECT) == 0 || BM_elem_flag_test(v, BM_ELEM_HIDDEN)) {
- dists[i] = FLT_MAX;
+ dist = FLT_MAX;
}
else {
BLI_LINKSTACK_PUSH(queue, v);
-
- dists[i] = 0.0f;
+ dist = 0.0f;
}
+
+ dists[i] = dists_prev[i] = dist;
}
bm->elem_index_dirty &= ~BM_VERT;
}
@@ -1991,55 +1996,77 @@ static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float
BMVert *v;
LinkNode *lnk;
+ /* this is correct but slow to do each iteration,
+ * instead sync the dist's while clearing BM_ELEM_TAG (below) */
+#if 0
memcpy(dists_prev, dists, sizeof(float) * bm->totvert);
+#endif
while ((v = BLI_LINKSTACK_POP(queue))) {
- /* quick checks */
- bool has_edges = (v->e != NULL);
- bool has_faces = false;
+ BLI_assert(dists[BM_elem_index_get(v)] != FLT_MAX);
/* connected edge-verts */
- if (has_edges) {
- BMIter iter;
- BMEdge *e;
+ if (v->e != NULL) {
+ BMEdge *e_iter, *e_first;
+
+ e_iter = e_first = v->e;
- BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
- has_faces |= (BM_edge_is_wire(e) == false);
+ /* would normally use BM_EDGES_OF_VERT, but this runs so often,
+ * its faster to iterate on the data directly */
+ do {
- if (BM_elem_flag_test(e, BM_ELEM_HIDDEN) == 0) {
- BMVert *v_other = BM_edge_other_vert(e, v);
+ if (BM_elem_flag_test(e_iter, BM_ELEM_HIDDEN) == 0) {
+
+ /* edge distance */
+ BMVert *v_other = BM_edge_other_vert(e_iter, v);
if (bmesh_test_dist_add(v, v_other, dists, dists_prev, mtx)) {
if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
BM_elem_flag_enable(v_other, BM_ELEM_TAG);
BLI_LINKSTACK_PUSH(queue_next, v_other);
}
}
- }
- }
- }
-
- /* imaginary edge diagonally across quad */
- if (has_faces) {
- BMIter iter;
- BMLoop *l;
- BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
- if ((BM_elem_flag_test(l->f, BM_ELEM_HIDDEN) == 0) && (l->f->len == 4)) {
- BMVert *v_other = l->next->next->v;
- if (bmesh_test_dist_add(v, v_other, dists, dists_prev, mtx)) {
- if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
- BM_elem_flag_enable(v_other, BM_ELEM_TAG);
- BLI_LINKSTACK_PUSH(queue_next, v_other);
- }
+ /* face distance */
+ if (e_iter->l) {
+ BMLoop *l_iter_radial, *l_first_radial;
+ /**
+ * imaginary edge diagonally across quad,
+ * \note, this takes advantage of the rules of winding that we
+ * know 2 or more of a verts edges wont reference the same face twice.
+ * Also, if the edge is hidden, the face will be hidden too.
+ */
+ l_iter_radial = l_first_radial = e_iter->l;
+
+ do {
+ if ((l_iter_radial->v == v) &&
+ (l_iter_radial->f->len == 4) &&
+ (BM_elem_flag_test(l_iter_radial->f, BM_ELEM_HIDDEN) == 0))
+ {
+ BMVert *v_other = l_iter_radial->next->next->v;
+ if (bmesh_test_dist_add(v, v_other, dists, dists_prev, mtx)) {
+ if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == 0) {
+ BM_elem_flag_enable(v_other, BM_ELEM_TAG);
+ BLI_LINKSTACK_PUSH(queue_next, v_other);
+ }
+ }
+ }
+ } while ((l_iter_radial = l_iter_radial->radial_next) != l_first_radial);
}
}
- }
+ } while ((e_iter = BM_DISK_EDGE_NEXT(e_iter, v)) != e_first);
}
}
+
/* clear for the next loop */
for (lnk = queue_next; lnk; lnk = lnk->next) {
- BM_elem_flag_disable((BMVert *)lnk->link, BM_ELEM_TAG);
+ BMVert *v = lnk->link;
+ const int i = BM_elem_index_get(v);
+
+ BM_elem_flag_disable(v, BM_ELEM_TAG);
+
+ /* keep in sync, avoid having to do full memcpy each iteration */
+ dists_prev[i] = dists[i];
}
BLI_LINKSTACK_SWAP(queue, queue_next);
@@ -2097,7 +2124,7 @@ static struct TransIslandData *editmesh_islands_info_calc(BMEditMesh *em, int *r
vert_map = MEM_mallocN(sizeof(*vert_map) * bm->totvert, __func__);
/* we shouldn't need this, but with incorrect selection flushing
* its possible we have a selected vertex thats not in a face, for now best not crash in that case. */
- fill_vn_i(vert_map, bm->totvert, -1);
+ copy_vn_i(vert_map, bm->totvert, -1);
BM_mesh_elem_table_ensure(bm, htype);
ele_array = (htype == BM_FACE) ? (void **)bm->ftable : (void **)bm->etable;
@@ -2257,7 +2284,7 @@ static void createTransEditVerts(TransInfo *t)
float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
float *dists = NULL;
int a;
- int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0;
+ const int prop_mode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0;
int mirror = 0;
int cd_vert_bweight_offset = -1;
bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
@@ -2297,7 +2324,7 @@ static void createTransEditVerts(TransInfo *t)
cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
}
- if (propmode) {
+ if (prop_mode) {
unsigned int count = 0;
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
@@ -2308,7 +2335,7 @@ static void createTransEditVerts(TransInfo *t)
t->total = count;
/* allocating scratch arrays */
- if (propmode & T_PROP_CONNECTED)
+ if (prop_mode & T_PROP_CONNECTED)
dists = MEM_mallocN(em->bm->totvert * sizeof(float), "scratch nears");
}
else {
@@ -2330,7 +2357,7 @@ static void createTransEditVerts(TransInfo *t)
* matrix inversion still works and we can still moving along the other */
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
- if (propmode & T_PROP_CONNECTED) {
+ if (prop_mode & T_PROP_CONNECTED) {
editmesh_set_connectivity_distance(em->bm, mtx, dists);
}
@@ -2359,7 +2386,7 @@ static void createTransEditVerts(TransInfo *t)
{
mappedcos = BKE_crazyspace_get_mapped_editverts(t->scene, t->obedit);
quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats");
- BKE_crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats, !propmode);
+ BKE_crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats, !prop_mode);
if (mappedcos)
MEM_freeN(mappedcos);
}
@@ -2384,7 +2411,7 @@ static void createTransEditVerts(TransInfo *t)
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
- if (propmode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
+ if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
struct TransIslandData *v_island = (island_info && island_vert_map[a] != -1) ?
&island_info[island_vert_map[a]] : NULL;
float *bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) : NULL;
@@ -2397,8 +2424,8 @@ static void createTransEditVerts(TransInfo *t)
if (BM_elem_flag_test(eve, BM_ELEM_SELECT))
tob->flag |= TD_SELECTED;
- if (propmode) {
- if (propmode & T_PROP_CONNECTED) {
+ if (prop_mode) {
+ if (prop_mode & T_PROP_CONNECTED) {
tob->dist = dists[a];
}
else {
@@ -2650,24 +2677,23 @@ void flushTransSeq(TransInfo *t)
/* ********************* UV ****************** */
-static void UVsToTransData(SpaceImage *sima, TransData *td, TransData2D *td2d, float *uv, int selected)
+static void UVsToTransData(
+ const float aspect[2], TransData *td, TransData2D *td2d,
+ float *uv, const float *center, bool selected)
{
- float aspx, aspy;
-
- ED_space_image_get_uv_aspect(sima, &aspx, &aspy);
-
/* uv coords are scaled by aspects. this is needed for rotations and
* proportional editing to be consistent with the stretched uv coords
* that are displayed. this also means that for display and numinput,
* and when the uv coords are flushed, these are converted each time */
- td2d->loc[0] = uv[0] * aspx;
- td2d->loc[1] = uv[1] * aspy;
+ td2d->loc[0] = uv[0] * aspect[0];
+ td2d->loc[1] = uv[1] * aspect[1];
td2d->loc[2] = 0.0f;
td2d->loc2d = uv;
td->flag = 0;
td->loc = td2d->loc;
- copy_v3_v3(td->center, td->loc);
+ copy_v2_v2(td->center, center ? center : td->loc);
+ td->center[2] = 0.0f;
copy_v3_v3(td->iloc, td->loc);
memset(td->axismtx, 0, sizeof(td->axismtx));
@@ -2694,36 +2720,43 @@ static void createTransUVs(bContext *C, TransInfo *t)
ToolSettings *ts = CTX_data_tool_settings(C);
TransData *td = NULL;
TransData2D *td2d = NULL;
- MTexPoly *tf;
- MLoopUV *luv;
BMEditMesh *em = BKE_editmesh_from_object(t->obedit);
BMFace *efa;
- BMLoop *l;
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 propmode = (t->flag & T_PROP_EDIT) != 0;
- const bool propconnected = (t->flag & T_PROP_CONNECTED) != 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_LOCAL);
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
+ const int cd_poly_tex_offset = CustomData_get_offset(&em->bm->pdata, CD_MTEXPOLY);
- if (!ED_space_image_show_uvedit(sima, t->obedit)) return;
+ if (!ED_space_image_show_uvedit(sima, t->obedit))
+ return;
/* count */
- if (propconnected) {
+ if (is_prop_connected || is_island_center) {
/* create element map with island information */
- if (ts->uv_flag & UV_SYNC_SELECTION) {
- elementmap = BM_uv_element_map_create(em->bm, false, true);
+ const bool use_facesel = (ts->uv_flag & UV_SYNC_SELECTION) == 0;
+ elementmap = BM_uv_element_map_create(em->bm, use_facesel, false, true);
+ if (elementmap == NULL) {
+ return;
}
- else {
- elementmap = BM_uv_element_map_create(em->bm, true, true);
+
+ if (is_prop_connected) {
+ island_enabled = BLI_BITMAP_NEW(elementmap->totalIslands, "TransIslandData(UV Editing)");
+ }
+
+ if (is_island_center) {
+ island_center = MEM_callocN(sizeof(*island_center) * elementmap->totalIslands, __func__);
}
- island_enabled = BLI_BITMAP_NEW(elementmap->totalIslands, "TransIslandData(UV Editing)");
}
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
- tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
+ MTexPoly *tf = BM_ELEM_CD_GET_VOID_P(efa, cd_poly_tex_offset);
+ BMLoop *l;
if (!uvedit_face_visible_test(scene, ima, efa, tf)) {
BM_elem_flag_disable(efa, BM_ELEM_TAG);
@@ -2735,14 +2768,25 @@ static void createTransUVs(bContext *C, TransInfo *t)
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
countsel++;
- if (propconnected) {
+ if (is_prop_connected || island_center) {
UvElement *element = BM_uv_element_get(elementmap, efa, l);
- BLI_BITMAP_ENABLE(island_enabled, element->island);
- }
+ if (is_prop_connected) {
+ BLI_BITMAP_ENABLE(island_enabled, element->island);
+ }
+
+ if (is_island_center) {
+ if (element->flag == false) {
+ MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+ add_v2_v2(island_center[element->island].co, luv->uv);
+ island_center[element->island].co_num++;
+ element->flag = true;
+ }
+ }
+ }
}
- if (propmode) {
+ if (is_prop_edit) {
count++;
}
}
@@ -2750,13 +2794,19 @@ static void createTransUVs(bContext *C, TransInfo *t)
/* note: in prop mode we need at least 1 selected */
if (countsel == 0) {
- if (propconnected) {
- MEM_freeN(island_enabled);
+ goto finally;
+ }
+
+ if (is_island_center) {
+ int i;
+
+ for (i = 0; i < elementmap->totalIslands; i++) {
+ mul_v2_fl(island_center[i].co, 1.0f / island_center[i].co_num);
+ mul_v2_v2(island_center[i].co, t->aspect);
}
- return;
}
- t->total = (propmode) ? count : countsel;
+ t->total = (is_prop_edit) ? count : countsel;
t->data = MEM_callocN(t->total * 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 */
@@ -2769,56 +2819,88 @@ static void createTransUVs(bContext *C, TransInfo *t)
td2d = t->data2d;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BMLoop *l;
+
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
continue;
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
- if (!propmode && !uvedit_uv_select_test(scene, l, cd_loop_uv_offset))
+ const bool selected = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
+ MLoopUV *luv;
+ const float *center = NULL;
+
+ if (!is_prop_edit && !selected)
continue;
- if (propconnected) {
+ if (is_prop_connected || is_island_center) {
UvElement *element = BM_uv_element_get(elementmap, efa, l);
- if (!BLI_BITMAP_TEST(island_enabled, element->island)) {
- count_rejected++;
- continue;
+
+ if (is_prop_connected) {
+ if (!BLI_BITMAP_TEST(island_enabled, element->island)) {
+ count_rejected++;
+ continue;
+ }
+ }
+
+ if (is_island_center) {
+ center = island_center[element->island].co;
}
}
+ BM_elem_flag_enable(l, BM_ELEM_TAG);
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
- UVsToTransData(sima, td++, td2d++, luv->uv, uvedit_uv_select_test(scene, l, cd_loop_uv_offset));
+ UVsToTransData(t->aspect, td++, td2d++, luv->uv, center, selected);
}
}
- if (propconnected) {
+ if (is_prop_connected) {
t->total -= count_rejected;
- BM_uv_element_map_free(elementmap);
- MEM_freeN(island_enabled);
}
if (sima->flag & SI_LIVE_UNWRAP)
ED_uvedit_live_unwrap_begin(t->scene, t->obedit);
+
+
+finally:
+ if (is_prop_connected || is_island_center) {
+ BM_uv_element_map_free(elementmap);
+
+ if (is_prop_connected) {
+ MEM_freeN(island_enabled);
+ }
+
+ if (island_center) {
+ MEM_freeN(island_center);
+ }
+ }
}
void flushTransUVs(TransInfo *t)
{
SpaceImage *sima = t->sa->spacedata.first;
TransData2D *td;
- int a, width, height;
- float aspx, aspy, invx, invy;
+ int a;
+ float aspect_inv[2], size[2];
+ const bool use_pixel_snap = ((sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL));
- ED_space_image_get_uv_aspect(sima, &aspx, &aspy);
- ED_space_image_get_size(sima, &width, &height);
- invx = 1.0f / aspx;
- invy = 1.0f / aspy;
+ aspect_inv[0] = 1.0f / t->aspect[0];
+ aspect_inv[1] = 1.0f / t->aspect[1];
+
+ if (use_pixel_snap) {
+ int size_i[2];
+ ED_space_image_get_size(sima, &size_i[0], &size_i[1]);
+ size[0] = size_i[0];
+ size[1] = size_i[1];
+ }
/* flush to 2d vector from internally used 3d vector */
for (a = 0, td = t->data2d; a < t->total; a++, td++) {
- td->loc2d[0] = td->loc[0] * invx;
- td->loc2d[1] = td->loc[1] * invy;
+ td->loc2d[0] = td->loc[0] * aspect_inv[0];
+ td->loc2d[1] = td->loc[1] * aspect_inv[1];
- if ((sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL)) {
- td->loc2d[0] = roundf(width * td->loc2d[0]) / width;
- td->loc2d[1] = roundf(height * td->loc2d[1]) / height;
+ if (use_pixel_snap) {
+ td->loc2d[0] = roundf(td->loc2d[0] * size[0]) / size[0];
+ td->loc2d[1] = roundf(td->loc2d[1] * size[1]) / size[1];
}
}
}
@@ -2826,44 +2908,45 @@ void flushTransUVs(TransInfo *t)
bool clipUVTransform(TransInfo *t, float vec[2], const bool resize)
{
TransData *td;
- int a, clipx = 1, clipy = 1;
- float aspx, aspy, min[2], max[2];
+ int a;
+ bool clipx = true, clipy = true;
+ float min[2], max[2];
- ED_space_image_get_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
min[0] = min[1] = 0.0f;
- max[0] = aspx; max[1] = aspy;
+ max[0] = t->aspect[0];
+ max[1] = t->aspect[1];
for (a = 0, td = t->data; a < t->total; a++, td++) {
minmax_v2v2_v2(min, max, td->loc);
}
if (resize) {
- if (min[0] < 0.0f && t->center[0] > 0.0f && t->center[0] < aspx * 0.5f)
+ 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] > aspx && t->center[0] < aspx)
- vec[0] *= (t->center[0] - aspx) / (t->center[0] - max[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]);
else
clipx = 0;
- if (min[1] < 0.0f && t->center[1] > 0.0f && t->center[1] < aspy * 0.5f)
+ 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] > aspy && t->center[1] < aspy)
- vec[1] *= (t->center[1] - aspy) / (t->center[1] - max[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]);
else
clipy = 0;
}
else {
if (min[0] < 0.0f)
vec[0] -= min[0];
- else if (max[0] > aspx)
- vec[0] -= max[0] - aspx;
+ else if (max[0] > t->aspect[0])
+ vec[0] -= max[0] - t->aspect[0];
else
clipx = 0;
if (min[1] < 0.0f)
vec[1] -= min[1];
- else if (max[1] > aspy)
- vec[1] -= max[1] - aspy;
+ else if (max[1] > t->aspect[1])
+ vec[1] -= max[1] - t->aspect[1];
else
clipy = 0;
}
@@ -2875,9 +2958,6 @@ void clipUVData(TransInfo *t)
{
TransData *td = NULL;
int a;
- float aspx, aspy;
-
- ED_space_image_get_uv_aspect(t->sa->spacedata.first, &aspx, &aspy);
for (a = 0, td = t->data; a < t->total; a++, td++) {
if (td->flag & TD_NOACTION)
@@ -2886,8 +2966,8 @@ void clipUVData(TransInfo *t)
if ((td->flag & TD_SKIP) || (!td->loc))
continue;
- td->loc[0] = min_ff(max_ff(0.0f, td->loc[0]), aspx);
- td->loc[1] = min_ff(max_ff(0.0f, td->loc[1]), aspy);
+ 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]);
}
}
@@ -3161,7 +3241,7 @@ static void posttrans_gpd_clean(bGPdata *gpd)
bGPDframe *gpf, *gpfn;
bool is_double = false;
- BLI_listbase_sort_r(&gpl->frames, &is_double, gpf_cmp_frame);
+ BLI_listbase_sort_r(&gpl->frames, gpf_cmp_frame, &is_double);
if (is_double) {
for (gpf = gpl->frames.first; gpf; gpf = gpfn) {
@@ -3188,7 +3268,7 @@ static void posttrans_mask_clean(Mask *mask)
MaskLayerShape *masklay_shape, *masklay_shape_next;
bool is_double = false;
- BLI_listbase_sort_r(&masklay->splines_shapes, &is_double, masklay_shape_cmp_frame);
+ BLI_listbase_sort_r(&masklay->splines_shapes, masklay_shape_cmp_frame, &is_double);
if (is_double) {
for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape_next) {
@@ -3304,76 +3384,90 @@ static void posttrans_action_clean(bAnimContext *ac, bAction *act)
/* ----------------------------- */
/* fully select selected beztriples, but only include if it's on the right side of cfra */
-static int count_fcurve_keys(FCurve *fcu, char side, float cfra)
+static int count_fcurve_keys(FCurve *fcu, char side, float cfra, bool is_prop_edit)
{
BezTriple *bezt;
- int i, count = 0;
+ int i, count = 0, count_all = 0;
if (ELEM(NULL, fcu, fcu->bezt))
return count;
/* only include points that occur on the right side of cfra */
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
- if (bezt->f2 & SELECT) {
+ if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
/* no need to adjust the handle selection since they are assumed
* selected (like graph editor with SIPO_NOHANDLES) */
- if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
- count += 1;
- }
+ if (bezt->f2 & SELECT)
+ count++;
+
+ count_all++;
}
}
- return count;
+ if (is_prop_edit && count > 0)
+ return count_all;
+ else return count;
}
/* fully select selected beztriples, but only include if it's on the right side of cfra */
-static int count_gplayer_frames(bGPDlayer *gpl, char side, float cfra)
+static int count_gplayer_frames(bGPDlayer *gpl, char side, float cfra, bool is_prop_edit)
{
bGPDframe *gpf;
- int count = 0;
+ int count = 0, count_all = 0;
if (gpl == NULL)
return count;
/* only include points that occur on the right side of cfra */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
- if (gpf->flag & GP_FRAME_SELECT) {
- if (FrameOnMouseSide(side, (float)gpf->framenum, cfra))
+ if (FrameOnMouseSide(side, (float)gpf->framenum, cfra)) {
+ if (gpf->flag & GP_FRAME_SELECT)
count++;
+ count_all++;
}
}
- return count;
+ if (is_prop_edit && count > 0)
+ return count_all;
+ else
+ return count;
}
/* fully select selected beztriples, but only include if it's on the right side of cfra */
-static int count_masklayer_frames(MaskLayer *masklay, char side, float cfra)
+static int count_masklayer_frames(MaskLayer *masklay, char side, float cfra, bool is_prop_edit)
{
MaskLayerShape *masklayer_shape;
- int count = 0;
+ int count = 0, count_all = 0;
if (masklay == NULL)
return count;
/* only include points that occur on the right side of cfra */
for (masklayer_shape = masklay->splines_shapes.first; masklayer_shape; masklayer_shape = masklayer_shape->next) {
- if (masklayer_shape->flag & MASK_SHAPE_SELECT) {
- if (FrameOnMouseSide(side, (float)masklayer_shape->frame, cfra))
+ if (FrameOnMouseSide(side, (float)masklayer_shape->frame, cfra)) {
+ if (masklayer_shape->flag & MASK_SHAPE_SELECT)
count++;
+ count_all++;
}
}
- return count;
+ if (is_prop_edit && count > 0)
+ return count_all;
+ else
+ return count;
}
/* This function assigns the information to transdata */
-static void TimeToTransData(TransData *td, float *time, AnimData *adt)
+static void TimeToTransData(TransData *td, float *time, AnimData *adt, float ypos)
{
/* memory is calloc'ed, so that should zero everything nicely for us */
td->val = time;
td->ival = *(time);
+ td->center[0] = td->ival;
+ td->center[1] = ypos;
+
/* store the AnimData where this keyframe exists as a keyframe of the
* active action as td->extra.
*/
@@ -3387,7 +3481,7 @@ static void TimeToTransData(TransData *td, float *time, AnimData *adt)
* The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data
* on the named side are used.
*/
-static TransData *ActionFCurveToTransData(TransData *td, TransData2D **td2dv, FCurve *fcu, AnimData *adt, char side, float cfra)
+static TransData *ActionFCurveToTransData(TransData *td, TransData2D **td2dv, FCurve *fcu, AnimData *adt, char side, float cfra, bool is_prop_edit, float ypos)
{
BezTriple *bezt;
TransData2D *td2d = *td2dv;
@@ -3398,11 +3492,14 @@ static TransData *ActionFCurveToTransData(TransData *td, TransData2D **td2dv, FC
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
/* only add selected keyframes (for now, proportional edit is not enabled) */
- if (bezt->f2 & SELECT) { /* note this MUST match count_fcurve_keys(), so can't use BEZSELECTED() macro */
+ if (is_prop_edit || (bezt->f2 & SELECT)) { /* note this MUST match count_fcurve_keys(), so can't use BEZSELECTED() macro */
/* only add if on the right 'side' of the current frame */
if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
- TimeToTransData(td, bezt->vec[1], adt);
+ TimeToTransData(td, bezt->vec[1], adt, ypos);
+ if (bezt->f2 & SELECT)
+ td->flag |= TD_SELECTED;
+
/*set flags to move handles as necessary*/
td->flag |= TD_MOVEHANDLE1 | TD_MOVEHANDLE2;
td2d->h1 = bezt->vec[0];
@@ -3453,19 +3550,22 @@ void flushTransIntFrameActionData(TransInfo *t)
* The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data
* on the named side are used.
*/
-static int GPLayerToTransData(TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl, char side, float cfra)
+static int GPLayerToTransData(TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl, char side, float cfra, bool is_prop_edit, float ypos)
{
bGPDframe *gpf;
int count = 0;
/* check for select frames on right side of current frame */
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
- if (gpf->flag & GP_FRAME_SELECT) {
+ if (is_prop_edit || (gpf->flag & GP_FRAME_SELECT)) {
if (FrameOnMouseSide(side, (float)gpf->framenum, cfra)) {
/* memory is calloc'ed, so that should zero everything nicely for us */
td->val = &tfd->val;
td->ival = (float)gpf->framenum;
+ td->center[0] = td->ival;
+ td->center[1] = ypos;
+
tfd->val = (float)gpf->framenum;
tfd->sdata = &gpf->framenum;
@@ -3481,19 +3581,22 @@ static int GPLayerToTransData(TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl,
}
/* refer to comment above #GPLayerToTransData, this is the same but for masks */
-static int MaskLayerToTransData(TransData *td, tGPFtransdata *tfd, MaskLayer *masklay, char side, float cfra)
+static int MaskLayerToTransData(TransData *td, tGPFtransdata *tfd, MaskLayer *masklay, char side, float cfra, bool is_prop_edit, float ypos)
{
MaskLayerShape *masklay_shape;
int count = 0;
/* check for select frames on right side of current frame */
for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) {
- if (masklay_shape->flag & MASK_SHAPE_SELECT) {
+ if (is_prop_edit || (masklay_shape->flag & MASK_SHAPE_SELECT)) {
if (FrameOnMouseSide(side, (float)masklay_shape->frame, cfra)) {
/* memory is calloc'ed, so that should zero everything nicely for us */
td->val = &tfd->val;
td->ival = (float)masklay_shape->frame;
+ td->center[0] = td->ival;
+ td->center[1] = ypos;
+
tfd->val = (float)masklay_shape->frame;
tfd->sdata = &masklay_shape->frame;
@@ -3515,15 +3618,25 @@ static void createTransActionData(bContext *C, TransInfo *t)
TransData *td = NULL;
TransData2D *td2d = NULL;
tGPFtransdata *tfd = NULL;
-
+
+ rcti *mask = &t->ar->v2d.mask;
+ rctf *datamask = &t->ar->v2d.cur;
+
+ float xsize = BLI_rctf_size_x(datamask);
+ float ysize = BLI_rctf_size_y(datamask);
+ float xmask = BLI_rcti_size_x(mask);
+ float ymask = BLI_rcti_size_y(mask);
+
bAnimContext ac;
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
int filter;
-
+ const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
+
int count = 0;
float cfra;
-
+ float ypos = 1.0f / ((ysize / xsize) * (xmask / ymask)) * BLI_rctf_cent_y(&t->ar->v2d.cur);
+
/* determine what type of data we are operating on */
if (ANIM_animdata_get_context(C, &ac) == 0)
return;
@@ -3551,7 +3664,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
/* loop 1: fully select ipo-keys and count how many BezTriples are selected */
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
-
+ int adt_count = 0;
/* convert current-frame to action-time (slightly less accurate, especially under
* higher scaling ratios, but is faster than converting all points)
*/
@@ -3560,14 +3673,19 @@ static void createTransActionData(bContext *C, TransInfo *t)
else
cfra = (float)CFRA;
- if (ale->type == ANIMTYPE_FCURVE)
- count += count_fcurve_keys(ale->key_data, t->frame_side, cfra);
+ if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE))
+ adt_count = count_fcurve_keys(ale->key_data, t->frame_side, cfra, is_prop_edit);
else if (ale->type == ANIMTYPE_GPLAYER)
- count += count_gplayer_frames(ale->data, t->frame_side, cfra);
+ adt_count = count_gplayer_frames(ale->data, t->frame_side, cfra, is_prop_edit);
else if (ale->type == ANIMTYPE_MASKLAYER)
- count += count_masklayer_frames(ale->data, t->frame_side, cfra);
+ adt_count = count_masklayer_frames(ale->data, t->frame_side, cfra, is_prop_edit);
else
BLI_assert(0);
+
+ if (adt_count > 0) {
+ count += adt_count;
+ ale->tag = true;
+ }
}
/* stop if trying to build list if nothing selected */
@@ -3604,11 +3722,22 @@ static void createTransActionData(bContext *C, TransInfo *t)
/* loop 2: build transdata array */
for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt;
+
+ if (is_prop_edit && !ale->tag)
+ continue;
+
+ adt = ANIM_nla_mapping_get(&ac, ale);
+ if (adt)
+ cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+ else
+ cfra = (float)CFRA;
+
if (ale->type == ANIMTYPE_GPLAYER) {
bGPDlayer *gpl = (bGPDlayer *)ale->data;
int i;
- i = GPLayerToTransData(td, tfd, gpl, t->frame_side, cfra);
+ i = GPLayerToTransData(td, tfd, gpl, t->frame_side, cfra, is_prop_edit, ypos);
td += i;
tfd += i;
}
@@ -3616,7 +3745,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
MaskLayer *masklay = (MaskLayer *)ale->data;
int i;
- i = MaskLayerToTransData(td, tfd, masklay, t->frame_side, cfra);
+ i = MaskLayerToTransData(td, tfd, masklay, t->frame_side, cfra, is_prop_edit, ypos);
td += i;
tfd += i;
}
@@ -3624,15 +3753,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
FCurve *fcu = (FCurve *)ale->key_data;
- /* convert current-frame to action-time (slightly less accurate, especially under
- * higher scaling ratios, but is faster than converting all points)
- */
- if (adt)
- cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
- else
- cfra = (float)CFRA;
-
- td = ActionFCurveToTransData(td, &td2d, fcu, adt, t->frame_side, cfra);
+ td = ActionFCurveToTransData(td, &td2d, fcu, adt, t->frame_side, cfra, is_prop_edit, ypos);
}
}
@@ -3661,6 +3782,109 @@ static void createTransActionData(bContext *C, TransInfo *t)
*((float *)(t->customData) + 1) = max;
}
+ /* calculate distances for proportional editing */
+ if (is_prop_edit) {
+ td = t->data;
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt;
+
+ /* F-Curve may not have any keyframes */
+ if (!ale->tag)
+ continue;
+
+ adt = ANIM_nla_mapping_get(&ac, ale);
+ if (adt)
+ cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+ else
+ cfra = (float)CFRA;
+
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+ bGPDframe *gpf;
+
+ for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+ if (gpf->flag & GP_FRAME_SELECT) {
+ td->dist = td->rdist = 0.0f;
+ }
+ else {
+ bGPDframe *gpf_iter;
+ int min = INT_MAX;
+ for (gpf_iter = gpl->frames.first; gpf_iter; gpf_iter = gpf->next) {
+ if (gpf_iter->flag & GP_FRAME_SELECT) {
+ if (FrameOnMouseSide(t->frame_side, (float)gpf_iter->framenum, cfra)) {
+ int val = abs(gpf->framenum - gpf_iter->framenum);
+ if (val < min) {
+ min = val;
+ }
+ }
+ }
+ }
+ td->dist = td->rdist = min;
+ }
+ td++;
+ }
+ }
+ else if (ale->type == ANIMTYPE_MASKLAYER) {
+ MaskLayer *masklay = (MaskLayer *)ale->data;
+ MaskLayerShape *masklay_shape;
+
+ for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) {
+ if (FrameOnMouseSide(t->frame_side, (float)masklay_shape->frame, cfra)) {
+ if (masklay_shape->flag & MASK_SHAPE_SELECT) {
+ td->dist = td->rdist = 0.0f;
+ }
+ else {
+ MaskLayerShape *masklay_iter;
+ int min = INT_MAX;
+ for (masklay_iter = masklay->splines_shapes.first; masklay_iter; masklay_iter = masklay_iter->next) {
+ if (masklay_iter->flag & MASK_SHAPE_SELECT) {
+ if (FrameOnMouseSide(t->frame_side, (float)masklay_iter->frame, cfra)) {
+ int val = abs(masklay_shape->frame - masklay_iter->frame);
+ if (val < min) {
+ min = val;
+ }
+ }
+ }
+ }
+ td->dist = td->rdist = min;
+ }
+ td++;
+ }
+ }
+ }
+ else {
+ FCurve *fcu = (FCurve *)ale->key_data;
+ BezTriple *bezt;
+ int i;
+
+ for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
+ if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) {
+ if (bezt->f2 & SELECT) {
+ td->dist = td->rdist = 0.0f;
+ }
+ else {
+ BezTriple *bezt_iter;
+ int j;
+ float min = FLT_MAX;
+ for (j = 0, bezt_iter = fcu->bezt; j < fcu->totvert; j++, bezt_iter++) {
+ if (bezt_iter->f2 & SELECT) {
+ if (FrameOnMouseSide(t->frame_side, (float)bezt_iter->vec[1][0], cfra)) {
+ float val = fabs(bezt->vec[1][0] - bezt_iter->vec[1][0]);
+ if (val < min)
+ min = val;
+ }
+ }
+ }
+ td->dist = td->rdist = min;
+ }
+ td++;
+ }
+ }
+ }
+ }
+ }
+
/* cleanup temp list */
ANIM_animdata_freelist(&anim_data);
}
@@ -3669,6 +3893,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
typedef struct TransDataGraph {
float unit_scale;
+ float offset;
} TransDataGraph;
/* Helper function for createTransGraphEditData, which is responsible for associating
@@ -3677,7 +3902,7 @@ typedef struct TransDataGraph {
static void bezt_to_transdata(TransData *td, TransData2D *td2d, TransDataGraph *tdg,
AnimData *adt, BezTriple *bezt,
int bi, bool selected, bool ishandle, bool intvals,
- float mtx[3][3], float smtx[3][3], float unit_scale)
+ float mtx[3][3], float smtx[3][3], float unit_scale, float offset)
{
float *loc = bezt->vec[bi];
const float *cent = bezt->vec[1];
@@ -3691,26 +3916,26 @@ static void bezt_to_transdata(TransData *td, TransData2D *td2d, TransDataGraph *
if (adt) {
td2d->loc[0] = BKE_nla_tweakedit_remap(adt, loc[0], NLATIME_CONVERT_MAP);
- td2d->loc[1] = loc[1] * unit_scale;
+ td2d->loc[1] = (loc[1] + offset) * unit_scale;
td2d->loc[2] = 0.0f;
td2d->loc2d = loc;
td->loc = td2d->loc;
td->center[0] = BKE_nla_tweakedit_remap(adt, cent[0], NLATIME_CONVERT_MAP);
- td->center[1] = cent[1] * unit_scale;
+ td->center[1] = (cent[1] + offset) * unit_scale;
td->center[2] = 0.0f;
copy_v3_v3(td->iloc, td->loc);
}
else {
td2d->loc[0] = loc[0];
- td2d->loc[1] = loc[1] * unit_scale;
+ td2d->loc[1] = (loc[1] + offset) * unit_scale;
td2d->loc[2] = 0.0f;
td2d->loc2d = loc;
td->loc = td2d->loc;
copy_v3_v3(td->center, cent);
- td->center[1] *= unit_scale;
+ td->center[1] = (td->center[1] + offset) * unit_scale;
copy_v3_v3(td->iloc, td->loc);
}
@@ -3750,6 +3975,7 @@ static void bezt_to_transdata(TransData *td, TransData2D *td2d, TransDataGraph *
copy_m3_m3(td->smtx, smtx);
tdg->unit_scale = unit_scale;
+ tdg->offset = offset;
}
static bool graph_edit_is_translation_mode(TransInfo *t)
@@ -3762,6 +3988,29 @@ static bool graph_edit_use_local_center(TransInfo *t)
return (t->around == V3D_LOCAL) && !graph_edit_is_translation_mode(t);
}
+
+static void graph_key_shortest_dist(TransInfo *t, FCurve *fcu, TransData *td_start, TransData *td, int cfra, bool use_handle)
+{
+ int j = 0;
+ TransData *td_iter = td_start;
+
+ td->dist = FLT_MAX;
+ for (; j < fcu->totvert; j++) {
+ BezTriple *bezt = fcu->bezt + j;
+ if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) {
+ const bool sel2 = (bezt->f2 & SELECT) != 0;
+ const bool sel1 = use_handle ? (bezt->f1 & SELECT) != 0 : sel2;
+ const bool sel3 = use_handle ? (bezt->f3 & SELECT) != 0 : sel2;
+
+ if (sel1 || sel2 || sel3) {
+ td->dist = td->rdist = min_ff(td->dist, fabs(td_iter->center[0] - td->center[0]));
+ }
+
+ td_iter += 3;
+ }
+ }
+}
+
static void createTransGraphEditData(bContext *C, TransInfo *t)
{
SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first;
@@ -3784,6 +4033,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
const bool is_translation_mode = graph_edit_is_translation_mode(t);
const bool use_handle = !(sipo->flag & SIPO_NOHANDLES);
const bool use_local_center = graph_edit_use_local_center(t);
+ const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
short anim_map_flag = ANIM_UNITCONV_ONLYSEL | ANIM_UNITCONV_SELVERTS;
/* determine what type of data we are operating on */
@@ -3815,6 +4065,8 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
FCurve *fcu = (FCurve *)ale->key_data;
float cfra;
+ int curvecount = 0;
+ bool selected = false;
/* F-Curve may not have any keyframes */
if (fcu->bezt == NULL)
@@ -3835,20 +4087,34 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
const bool sel1 = use_handle ? (bezt->f1 & SELECT) != 0 : sel2;
const bool sel3 = use_handle ? (bezt->f3 & SELECT) != 0 : sel2;
- if (!is_translation_mode || !(sel2)) {
- if (sel1) {
- count++;
+ if (is_prop_edit) {
+ curvecount += 3;
+ if (sel2 || sel1 || sel3)
+ selected = true;
+ }
+ else {
+ if (!is_translation_mode || !(sel2)) {
+ if (sel1) {
+ count++;
+ }
+
+ if (sel3) {
+ count++;
+ }
}
- if (sel3) {
+ /* only include main vert if selected */
+ if (sel2 && !use_local_center) {
count++;
}
}
+ }
+ }
- /* only include main vert if selected */
- if (sel2 && !use_local_center) {
- count++;
- }
+ if (is_prop_edit) {
+ if (selected) {
+ count += curvecount;
+ ale->tag = true;
}
}
}
@@ -3897,11 +4163,11 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
FCurve *fcu = (FCurve *)ale->key_data;
bool intvals = (fcu->flag & FCURVE_INT_VALUES) != 0;
- float unit_scale;
+ float unit_scale, offset;
float cfra;
/* F-Curve may not have any keyframes */
- if (fcu->bezt == NULL)
+ if (fcu->bezt == NULL || (is_prop_edit && ale->tag == 0))
continue;
/* convert current-frame to action-time (slightly less accurate, especially under
@@ -3912,7 +4178,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
else
cfra = (float)CFRA;
- unit_scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, ale->key_data, anim_map_flag);
+ unit_scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, ale->key_data, anim_map_flag, &offset);
/* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse (if applicable) */
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
@@ -3924,66 +4190,135 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
TransDataCurveHandleFlags *hdata = NULL;
/* short h1=1, h2=1; */ /* UNUSED */
- /* only include handles if selected, irrespective of the interpolation modes.
- * also, only treat handles specially if the center point isn't selected.
- */
- if (!is_translation_mode || !(sel2)) {
- if (sel1) {
- hdata = initTransDataCurveHandles(td, bezt);
- bezt_to_transdata(td++, td2d++, tdg++, adt, bezt, 0, sel1, true, intvals, mtx, smtx, unit_scale);
+ if (is_prop_edit) {
+ bool is_sel = (sel2 || sel1 || sel3);
+ /* we always select all handles for proportional editing if central handle is selected */
+ initTransDataCurveHandles(td, bezt);
+ bezt_to_transdata(td++, td2d++, tdg++, adt, bezt, 0, is_sel, true, intvals, mtx, smtx, unit_scale, offset);
+ initTransDataCurveHandles(td, bezt);
+ bezt_to_transdata(td++, td2d++, tdg++, adt, bezt, 1, is_sel, false, intvals, mtx, smtx, unit_scale, offset);
+ initTransDataCurveHandles(td, bezt);
+ bezt_to_transdata(td++, td2d++, tdg++, adt, bezt, 2, is_sel, true, intvals, mtx, smtx, unit_scale, offset);
+ }
+ else {
+ /* only include handles if selected, irrespective of the interpolation modes.
+ * also, only treat handles specially if the center point isn't selected.
+ */
+ if (!is_translation_mode || !(sel2)) {
+ if (sel1) {
+ hdata = initTransDataCurveHandles(td, bezt);
+ bezt_to_transdata(td++, td2d++, tdg++, adt, bezt, 0, sel1, true, intvals, mtx, smtx, unit_scale, offset);
+ }
+ else {
+ /* h1 = 0; */ /* UNUSED */
+ }
+
+ if (sel3) {
+ if (hdata == NULL)
+ hdata = initTransDataCurveHandles(td, bezt);
+ bezt_to_transdata(td++, td2d++, tdg++, adt, bezt, 2, sel3, true, intvals, mtx, smtx, unit_scale, offset);
+ }
+ else {
+ /* h2 = 0; */ /* UNUSED */
+ }
}
- else {
- /* h1 = 0; */ /* UNUSED */
+
+ /* only include main vert if selected */
+ if (sel2 && !use_local_center) {
+ /* move handles relative to center */
+ if (is_translation_mode) {
+ if (sel1) td->flag |= TD_MOVEHANDLE1;
+ if (sel3) td->flag |= TD_MOVEHANDLE2;
+ }
+
+ /* if handles were not selected, store their selection status */
+ if (!(sel1) || !(sel3)) {
+ if (hdata == NULL)
+ hdata = initTransDataCurveHandles(td, bezt);
+ }
+
+ bezt_to_transdata(td++, td2d++, tdg++, adt, bezt, 1, sel2, false, intvals, mtx, smtx, unit_scale, offset);
+
}
-
- if (sel3) {
- if (hdata == NULL)
- hdata = initTransDataCurveHandles(td, bezt);
- bezt_to_transdata(td++, td2d++, tdg++, adt, bezt, 2, sel3, true, intvals, mtx, smtx, unit_scale);
+ /* special hack (must be done after initTransDataCurveHandles(), as that stores handle settings to restore...):
+ * - Check if we've got entire BezTriple selected and we're scaling/rotating that point,
+ * then check if we're using auto-handles.
+ * - If so, change them auto-handles to aligned handles so that handles get affected too
+ */
+ if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) &&
+ ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM) &&
+ ELEM(t->mode, TFM_ROTATION, TFM_RESIZE))
+ {
+ if (hdata && (sel1) && (sel3)) {
+ bezt->h1 = HD_ALIGN;
+ bezt->h2 = HD_ALIGN;
+ }
+ }
+ }
+ }
+ }
+
+ /* Sets handles based on the selection */
+ testhandles_fcurve(fcu, use_handle);
+ }
+
+ if (is_prop_edit) {
+ /* loop 2: build transdata arrays */
+ td = t->data;
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
+ FCurve *fcu = (FCurve *)ale->key_data;
+ TransData *td_start = td;
+ float cfra;
+
+ /* F-Curve may not have any keyframes */
+ if (fcu->bezt == NULL || (ale->tag == 0))
+ continue;
+
+ /* convert current-frame to action-time (slightly less accurate, especially under
+ * higher scaling ratios, but is faster than converting all points)
+ */
+ if (adt)
+ cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+ else
+ cfra = (float)CFRA;
+
+ /* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse (if applicable) */
+ for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
+ if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) {
+ const bool sel2 = (bezt->f2 & SELECT) != 0;
+ const bool sel1 = use_handle ? (bezt->f1 & SELECT) != 0 : sel2;
+ const bool sel3 = use_handle ? (bezt->f3 & SELECT) != 0 : sel2;
+
+ if (sel1 || sel2) {
+ td->dist = td->rdist = 0.0f;
}
else {
- /* h2 = 0; */ /* UNUSED */
+ graph_key_shortest_dist(t, fcu, td_start, td, cfra, use_handle);
}
- }
-
- /* only include main vert if selected */
- if (sel2 && !use_local_center) {
- /* move handles relative to center */
- if (is_translation_mode) {
- if (sel1) td->flag |= TD_MOVEHANDLE1;
- if (sel3) td->flag |= TD_MOVEHANDLE2;
+ td++;
+
+ if (sel2) {
+ td->dist = td->rdist = 0.0f;
}
-
- /* if handles were not selected, store their selection status */
- if (!(sel1) || !(sel3)) {
- if (hdata == NULL)
- hdata = initTransDataCurveHandles(td, bezt);
+ else {
+ graph_key_shortest_dist(t, fcu, td_start, td, cfra, use_handle);
}
-
- bezt_to_transdata(td++, td2d++, tdg++, adt, bezt, 1, sel2, false, intvals, mtx, smtx, unit_scale);
-
- }
- /* special hack (must be done after initTransDataCurveHandles(), as that stores handle settings to restore...):
- * - Check if we've got entire BezTriple selected and we're scaling/rotating that point,
- * then check if we're using auto-handles.
- * - If so, change them auto-handles to aligned handles so that handles get affected too
- */
- if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) &&
- ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM) &&
- ELEM(t->mode, TFM_ROTATION, TFM_RESIZE))
- {
- if (hdata && (sel1) && (sel3)) {
- bezt->h1 = HD_ALIGN;
- bezt->h2 = HD_ALIGN;
+ td++;
+
+ if (sel3 || sel2) {
+ td->dist = td->rdist = 0.0f;
+ }
+ else {
+ graph_key_shortest_dist(t, fcu, td_start, td, cfra, use_handle);
}
+ td++;
}
}
}
-
- /* Sets handles based on the selection */
- testhandles_fcurve(fcu, use_handle);
}
-
+
/* cleanup temp list */
ANIM_animdata_freelist(&anim_data);
}
@@ -4267,7 +4602,7 @@ void flushTransGraphData(TransInfo *t)
if (td->flag & TD_INTVALUES)
td2d->loc2d[1] = floorf(td2d->loc[1] + 0.5f);
else
- td2d->loc2d[1] = td2d->loc[1] * inv_unit_scale;
+ td2d->loc2d[1] = td2d->loc[1] * inv_unit_scale - tdg->offset;
if ((td->flag & TD_MOVEHANDLE1) && td2d->h1) {
td2d->h1[0] = td2d->ih1[0] + td->loc[0] - td->iloc[0];
@@ -5080,7 +5415,9 @@ static void set_trans_object_base_flags(TransInfo *t)
}
/* all recalc flags get flushed to all layers, so a layer flip later on works fine */
+#ifdef WITH_LEGACY_DEPSGRAPH
DAG_scene_flush_update(G.main, t->scene, -1, 0);
+#endif
/* and we store them temporal in base (only used for transform code) */
/* this because after doing updates, the object->recalc is cleared */
@@ -5157,7 +5494,9 @@ static int count_proportional_objects(TransInfo *t)
/* all recalc flags get flushed to all layers, so a layer flip later on works fine */
DAG_scene_relations_update(G.main, t->scene);
+#ifdef WITH_LEGACY_DEPSGRAPH
DAG_scene_flush_update(G.main, t->scene, -1, 0);
+#endif
/* and we store them temporal in base (only used for transform code) */
/* this because after doing updates, the object->recalc is cleared */
@@ -6039,7 +6378,7 @@ static void createTransObject(bContext *C, TransInfo *t)
TransData *td = NULL;
TransDataExtension *tx;
- int propmode = t->flag & T_PROP_EDIT;
+ const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
set_trans_object_base_flags(t);
@@ -6052,7 +6391,7 @@ static void createTransObject(bContext *C, TransInfo *t)
return;
}
- if (propmode) {
+ if (is_prop_edit) {
t->total += count_proportional_objects(t);
}
@@ -6085,7 +6424,7 @@ static void createTransObject(bContext *C, TransInfo *t)
}
CTX_DATA_END;
- if (propmode) {
+ if (is_prop_edit) {
View3D *v3d = t->view;
Base *base;
@@ -6239,22 +6578,22 @@ typedef struct TransDataTracking {
static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt,
MovieTrackingTrack *track, MovieTrackingMarker *marker,
- int area, float loc[2], float rel[2], const float off[2], float aspx, float aspy)
+ int area, float loc[2], float rel[2], const float off[2], const float aspect[2])
{
int anchor = area == TRACK_AREA_POINT && off;
tdt->mode = transDataTracking_ModeTracks;
if (anchor) {
- td2d->loc[0] = rel[0] * aspx; /* hold original location */
- td2d->loc[1] = rel[1] * aspy;
+ td2d->loc[0] = rel[0] * aspect[0]; /* hold original location */
+ td2d->loc[1] = rel[1] * aspect[1];
tdt->loc = loc;
td2d->loc2d = loc; /* current location */
}
else {
- td2d->loc[0] = loc[0] * aspx; /* hold original location */
- td2d->loc[1] = loc[1] * aspy;
+ td2d->loc[0] = loc[0] * aspect[0]; /* hold original location */
+ td2d->loc[1] = loc[1] * aspect[1];
td2d->loc2d = loc; /* current location */
}
@@ -6269,8 +6608,8 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra
if (rel) {
if (!anchor) {
- td2d->loc[0] += rel[0] * aspx;
- td2d->loc[1] += rel[1] * aspy;
+ td2d->loc[0] += rel[0] * aspect[0];
+ td2d->loc[1] += rel[1] * aspect[1];
}
copy_v2_v2(tdt->srelative, rel);
@@ -6285,8 +6624,8 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra
//copy_v3_v3(td->center, td->loc);
td->flag |= TD_INDIVIDUAL_SCALE;
- td->center[0] = marker->pos[0] * aspx;
- td->center[1] = marker->pos[1] * aspy;
+ td->center[0] = marker->pos[0] * aspect[0];
+ td->center[1] = marker->pos[1] * aspect[1];
memset(td->axismtx, 0, sizeof(td->axismtx));
td->axismtx[2][2] = 1.0f;
@@ -6301,8 +6640,9 @@ static void markerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTra
unit_m3(td->smtx);
}
-static void trackToTransData(const int framenr, TransData *td, TransData2D *td2d,
- TransDataTracking *tdt, MovieTrackingTrack *track, float aspx, float aspy)
+static void trackToTransData(
+ const int framenr, TransData *td, TransData2D *td2d,
+ TransDataTracking *tdt, MovieTrackingTrack *track, const float aspect[2])
{
MovieTrackingMarker *marker = BKE_tracking_marker_ensure(track, framenr);
@@ -6310,11 +6650,11 @@ static void trackToTransData(const int framenr, TransData *td, TransData2D *td2d
marker->flag &= ~(MARKER_DISABLED | MARKER_TRACKED);
markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_POINT,
- track->offset, marker->pos, track->offset, aspx, aspy);
+ track->offset, marker->pos, track->offset, aspect);
if (track->flag & SELECT) {
markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_POINT,
- marker->pos, NULL, NULL, aspx, aspy);
+ marker->pos, NULL, NULL, aspect);
}
if (track->pat_flag & SELECT) {
@@ -6322,28 +6662,28 @@ static void trackToTransData(const int framenr, TransData *td, TransData2D *td2d
for (a = 0; a < 4; a++) {
markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_PAT,
- marker->pattern_corners[a], marker->pos, NULL, aspx, aspy);
+ marker->pattern_corners[a], marker->pos, NULL, aspect);
}
}
if (track->search_flag & SELECT) {
markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_SEARCH,
- marker->search_min, marker->pos, NULL, aspx, aspy);
+ marker->search_min, marker->pos, NULL, aspect);
markerToTransDataInit(td++, td2d++, tdt++, track, marker, TRACK_AREA_SEARCH,
- marker->search_max, marker->pos, NULL, aspx, aspy);
+ marker->search_max, marker->pos, NULL, aspect);
}
}
static void planeMarkerToTransDataInit(TransData *td, TransData2D *td2d, TransDataTracking *tdt,
MovieTrackingPlaneTrack *plane_track, float corner[2],
- float aspx, float aspy)
+ const float aspect[2])
{
tdt->mode = transDataTracking_ModePlaneTracks;
tdt->plane_track = plane_track;
- td2d->loc[0] = corner[0] * aspx; /* hold original location */
- td2d->loc[1] = corner[1] * aspy;
+ td2d->loc[0] = corner[0] * aspect[0]; /* hold original location */
+ td2d->loc[1] = corner[1] * aspect[1];
td2d->loc2d = corner; /* current location */
td2d->loc[2] = 0.0f;
@@ -6368,7 +6708,7 @@ static void planeMarkerToTransDataInit(TransData *td, TransData2D *td2d, TransDa
static void planeTrackToTransData(const int framenr, TransData *td, TransData2D *td2d,
TransDataTracking *tdt, MovieTrackingPlaneTrack *plane_track,
- float aspx, float aspy)
+ const float aspect[2])
{
MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_ensure(plane_track, framenr);
int i;
@@ -6377,7 +6717,7 @@ static void planeTrackToTransData(const int framenr, TransData *td, TransData2D
plane_marker->flag &= ~PLANE_MARKER_TRACKED;
for (i = 0; i < 4; i++) {
- planeMarkerToTransDataInit(td++, td2d++, tdt++, plane_track, plane_marker->corners[i], aspx, aspy);
+ planeMarkerToTransDataInit(td++, td2d++, tdt++, plane_track, plane_marker->corners[i], aspect);
}
}
@@ -6406,7 +6746,6 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
MovieTrackingPlaneTrack *plane_track;
TransDataTracking *tdt;
int framenr = ED_space_clip_get_clip_frame_number(sc);
- float aspx, aspy;
/* count */
t->total = 0;
@@ -6441,8 +6780,6 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
if (t->total == 0)
return;
- ED_space_clip_get_aspect_dimension_aware(sc, &aspx, &aspy);
-
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");
@@ -6453,7 +6790,7 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
track = tracksbase->first;
while (track) {
if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_LOCKED) == 0) {
- trackToTransData(framenr, td, td2d, tdt, track, aspx, aspy);
+ trackToTransData(framenr, td, td2d, tdt, track, t->aspect);
/* offset */
td++;
@@ -6487,7 +6824,7 @@ static void createTransTrackingTracksData(bContext *C, TransInfo *t)
plane_track = plane_track->next)
{
if (PLANE_TRACK_VIEW_SELECTED(plane_track)) {
- planeTrackToTransData(framenr, td, td2d, tdt, plane_track, aspx, aspy);
+ planeTrackToTransData(framenr, td, td2d, tdt, plane_track, t->aspect);
td += 4;
td2d += 4;
tdt += 4;
@@ -6699,14 +7036,10 @@ static void cancelTransTracking(TransInfo *t)
void flushTransTracking(TransInfo *t)
{
- SpaceClip *sc = t->sa->spacedata.first;
TransData *td;
TransData2D *td2d;
TransDataTracking *tdt;
int a;
- float aspx, aspy;
-
- ED_space_clip_get_aspect_dimension_aware(sc, &aspx, &aspy);
if (t->state == TRANS_CANCEL)
cancelTransTracking(t);
@@ -6720,8 +7053,8 @@ void flushTransTracking(TransInfo *t)
continue;
}
- loc2d[0] = td2d->loc[0] / aspx;
- loc2d[1] = td2d->loc[1] / aspy;
+ loc2d[0] = td2d->loc[0] / t->aspect[0];
+ loc2d[1] = td2d->loc[1] / t->aspect[1];
if (t->flag & T_ALT_TRANSFORM) {
if (t->mode == TFM_RESIZE) {
@@ -6763,8 +7096,8 @@ void flushTransTracking(TransInfo *t)
td2d->loc2d[tdt->coord] = tdt->prev_pos[tdt->coord] + td2d->loc[1] * tdt->scale;
}
else if (tdt->mode == transDataTracking_ModePlaneTracks) {
- td2d->loc2d[0] = td2d->loc[0] / aspx;
- td2d->loc2d[1] = td2d->loc[1] / aspy;
+ td2d->loc2d[0] = td2d->loc[0] / t->aspect[0];
+ td2d->loc2d[1] = td2d->loc[1] / t->aspect[1];
}
}
}
@@ -6842,9 +7175,10 @@ static void MaskHandleToTransData(MaskSplinePoint *point, eMaskWhichHandle which
}
}
-static void MaskPointToTransData(Scene *scene, MaskSplinePoint *point,
- TransData *td, TransData2D *td2d, TransDataMasking *tdm,
- const int propmode, const float asp[2])
+static void MaskPointToTransData(
+ Scene *scene, MaskSplinePoint *point,
+ TransData *td, TransData2D *td2d, TransDataMasking *tdm,
+ const bool is_prop_edit, const float asp[2])
{
BezTriple *bezt = &point->bezt;
const bool is_sel_point = MASKPOINT_ISSEL_KNOT(point);
@@ -6854,7 +7188,7 @@ static void MaskPointToTransData(Scene *scene, MaskSplinePoint *point,
BKE_mask_point_parent_matrix_get(point, CFRA, parent_matrix);
invert_m3_m3(parent_inverse_matrix, parent_matrix);
- if (propmode || is_sel_point) {
+ if (is_prop_edit || is_sel_point) {
int i;
tdm->point = point;
@@ -6974,7 +7308,7 @@ static void createTransMaskingData(bContext *C, TransInfo *t)
TransData2D *td2d = NULL;
TransDataMasking *tdm = NULL;
int count = 0, countsel = 0;
- int propmode = t->flag & T_PROP_EDIT;
+ const bool is_prop_edit = (t->flag & T_PROP_EDIT);
float asp[2];
t->total = 0;
@@ -7024,7 +7358,7 @@ static void createTransMaskingData(bContext *C, TransInfo *t)
}
}
- if (propmode)
+ if (is_prop_edit)
count += 3;
}
}
@@ -7037,7 +7371,7 @@ static void createTransMaskingData(bContext *C, TransInfo *t)
ED_mask_get_aspect(t->sa, t->ar, &asp[0], &asp[1]);
- t->total = (propmode) ? count : countsel;
+ t->total = (is_prop_edit) ? count : countsel;
td = t->data = MEM_callocN(t->total * 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 */
@@ -7060,10 +7394,10 @@ static void createTransMaskingData(bContext *C, TransInfo *t)
for (i = 0; i < spline->tot_point; i++) {
MaskSplinePoint *point = &spline->points[i];
- if (propmode || MASKPOINT_ISSEL_ANY(point)) {
- MaskPointToTransData(scene, point, td, td2d, tdm, propmode, asp);
+ if (is_prop_edit || MASKPOINT_ISSEL_ANY(point)) {
+ MaskPointToTransData(scene, point, td, td2d, tdm, is_prop_edit, asp);
- if (propmode || MASKPOINT_ISSEL_KNOT(point)) {
+ if (is_prop_edit || MASKPOINT_ISSEL_KNOT(point)) {
td += 3;
td2d += 3;
tdm += 3;
@@ -7306,8 +7640,8 @@ static void createTransGPencil(bContext *C, TransInfo *t)
const Scene *scene = CTX_data_scene(C);
const int cfra = CFRA;
- const int propedit = (t->flag & T_PROP_EDIT);
- const int propedit_connected = (t->flag & T_PROP_CONNECTED);
+ const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
+ const bool is_prop_edit_connected = (t->flag & T_PROP_CONNECTED) != 0;
/* == Grease Pencil Strokes to Transform Data ==
@@ -7338,9 +7672,9 @@ static void createTransGPencil(bContext *C, TransInfo *t)
continue;
}
- if (propedit) {
+ if (is_prop_edit) {
/* Proportional Editing... */
- if (propedit_connected) {
+ if (is_prop_edit_connected) {
/* connected only - so only if selected */
if (gps->flag & GP_STROKE_SELECT)
t->total += gps->totpoints;
@@ -7447,8 +7781,8 @@ static void createTransGPencil(bContext *C, TransInfo *t)
}
/* What we need to include depends on proportional editing settings... */
- if (propedit) {
- if (propedit_connected) {
+ if (is_prop_edit) {
+ if (is_prop_edit_connected) {
/* A) "Connected" - Only those in selected strokes */
stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0;
}
@@ -7467,7 +7801,7 @@ static void createTransGPencil(bContext *C, TransInfo *t)
bGPDspoint *pt;
int i;
-#if 0 /* XXX: this isn't needed anymore; cannot calculate center this way or propedit breaks */
+#if 0 /* XXX: this isn't needed anymore; cannot calculate center this way or is_prop_edit breaks */
const float ninv = 1.0f / gps->totpoints;
float center[3] = {0.0f};
@@ -7482,7 +7816,7 @@ static void createTransGPencil(bContext *C, TransInfo *t)
bool point_ok;
/* include point? */
- if (propedit) {
+ if (is_prop_edit) {
/* Always all points in strokes that get included */
point_ok = true;
}
@@ -7525,7 +7859,7 @@ static void createTransGPencil(bContext *C, TransInfo *t)
}
/* March over these points, and calculate the proportional editing distances */
- if (propedit && (head != tail)) {
+ if (is_prop_edit && (head != tail)) {
/* XXX: for now, we are similar enough that this works... */
calc_distanceCurveVerts(head, tail - 1);
}
@@ -7594,6 +7928,12 @@ void createTransData(bContext *C, TransInfo *t)
else if (t->spacetype == SPACE_ACTION) {
t->flag |= T_POINTS | T_2D_EDIT;
createTransActionData(C, t);
+
+ if (t->data && (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);
+ }
}
else if (t->spacetype == SPACE_NLA) {
t->flag |= T_POINTS | T_2D_EDIT;
@@ -7607,13 +7947,12 @@ void createTransData(bContext *C, TransInfo *t)
else if (t->spacetype == SPACE_IPO) {
t->flag |= T_POINTS | T_2D_EDIT;
createTransGraphEditData(C, t);
-#if 0
+
if (t->data && (t->flag & T_PROP_EDIT)) {
sort_trans_data(t); // makes selected become first in array
- set_prop_dist(t, 1);
+ set_prop_dist(t, false); /* don't do that, distance has been set in createTransGraphEditData already */
sort_trans_data_dist(t);
}
-#endif
}
else if (t->spacetype == SPACE_NODE) {
t->flag |= T_POINTS | T_2D_EDIT;