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:
authorJoão Araújo <jaraujo98@gmail.com>2017-07-26 13:25:24 +0300
committerJoão Araújo <jaraujo98@gmail.com>2017-07-26 13:25:24 +0300
commit59908f5eb73670c97c5bb817290a0dac99089900 (patch)
tree709de097c1fac2ff7b172a8b50dc8a91d7b74860 /source/blender/editors/transform/transform_conversions.c
parent595f2ca2e06e07acaccc473982bde7a5ed644b50 (diff)
parentedc6bec9d60204cb81d2e7533402630b076d0d32 (diff)
Merge remote-tracking branch 'origin/master' into gsoc2016-improved_extrusiongsoc2016-improved_extrusion
Diffstat (limited to 'source/blender/editors/transform/transform_conversions.c')
-rw-r--r--source/blender/editors/transform/transform_conversions.c170
1 files changed, 132 insertions, 38 deletions
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 5e67f304755..4429d19613a 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -771,34 +771,43 @@ int count_set_pose_transflags(int *out_mode, short around, Object *ob)
/* -------- Auto-IK ---------- */
/* adjust pose-channel's auto-ik chainlen */
-static void pchan_autoik_adjust(bPoseChannel *pchan, short chainlen)
+static bool pchan_autoik_adjust(bPoseChannel *pchan, short chainlen)
{
bConstraint *con;
+ bool changed = false;
/* don't bother to search if no valid constraints */
- if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0)
- return;
+ if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0) {
+ return changed;
+ }
/* check if pchan has ik-constraint */
for (con = pchan->constraints.first; con; con = con->next) {
if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) {
bKinematicConstraint *data = con->data;
-
+
/* only accept if a temporary one (for auto-ik) */
if (data->flag & CONSTRAINT_IK_TEMP) {
/* chainlen is new chainlen, but is limited by maximum chainlen */
- if ((chainlen == 0) || (chainlen > data->max_rootbone))
+ const int old_rootbone = data->rootbone;
+ if ((chainlen == 0) || (chainlen > data->max_rootbone)) {
data->rootbone = data->max_rootbone;
- else
+ }
+ else {
data->rootbone = chainlen;
+ }
+ changed |= (data->rootbone != old_rootbone);
}
}
}
+
+ return changed;
}
/* change the chain-length of auto-ik */
void transform_autoik_update(TransInfo *t, short mode)
{
+ const short old_len = t->settings->autoik_chainlen;
short *chainlen = &t->settings->autoik_chainlen;
bPoseChannel *pchan;
@@ -812,13 +821,29 @@ void transform_autoik_update(TransInfo *t, short mode)
if (*chainlen > 0) (*chainlen)--;
}
+ /* IK length did not change, skip any updates. */
+ if (old_len == *chainlen) {
+ return;
+ }
+
/* 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) {
- pchan_autoik_adjust(pchan, *chainlen);
+ changed |= pchan_autoik_adjust(pchan, *chainlen);
+ }
+
+#ifdef WITH_LEGACY_DEPSGRAPH
+ if (!DEG_depsgraph_use_legacy())
+#endif
+ {
+ if (changed) {
+ /* TODO(sergey): Consider doing partial update only. */
+ DAG_relations_tag_update(G.main);
+ }
}
}
@@ -828,7 +853,9 @@ static void pose_grab_with_ik_clear(Object *ob)
bKinematicConstraint *data;
bPoseChannel *pchan;
bConstraint *con, *next;
+#ifdef WITH_LEGACY_DEPSGRAPH
bool need_dependency_update = false;
+#endif
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
/* clear all temporary lock flags */
@@ -843,7 +870,9 @@ static void pose_grab_with_ik_clear(Object *ob)
data = con->data;
if (data->flag & CONSTRAINT_IK_TEMP) {
/* iTaSC needs clear for removed constraints */
+#ifdef WITH_LEGACY_DEPSGRAPH
need_dependency_update = true;
+#endif
BIK_clear_data(ob->pose);
BLI_remlink(&pchan->constraints, con);
@@ -1496,6 +1525,48 @@ static TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struc
return hdata;
}
+/**
+ * For the purpose of transform code we need to behave as if handles are selected,
+ * even when they aren't (see special case below).
+ */
+static int bezt_select_to_transform_triple_flag(
+ const BezTriple *bezt, const bool hide_handles)
+{
+ int flag = 0;
+
+ if (hide_handles) {
+ if (bezt->f2 & SELECT) {
+ flag = (1 << 0) | (1 << 1) | (1 << 2);
+ }
+ }
+ else {
+ flag = (
+ ((bezt->f1 & SELECT) ? (1 << 0) : 0) |
+ ((bezt->f2 & SELECT) ? (1 << 1) : 0) |
+ ((bezt->f3 & SELECT) ? (1 << 2) : 0)
+ );
+ }
+
+ /* Special case for auto & aligned handles:
+ * When a center point is being moved without the handles,
+ * leaving the handles stationary makes no sense and only causes strange behavior,
+ * where one handle is arbitrarily anchored, the other one is aligned and lengthened
+ * based on where the center point is moved. Also a bug when cancelling, see: T52007.
+ *
+ * A more 'correct' solution could be to store handle locations in 'TransDataCurveHandleFlags'.
+ * However that doesn't resolve odd behavior, so best transform the handles in this case.
+ */
+ if ((flag != ((1 << 0) | (1 << 1) | (1 << 2))) && (flag & (1 << 1))) {
+ if (ELEM(bezt->h1, HD_AUTO, HD_ALIGN) &&
+ ELEM(bezt->h2, HD_AUTO, HD_ALIGN))
+ {
+ flag = (1 << 0) | (1 << 1) | (1 << 2);
+ }
+ }
+
+ return flag;
+}
+
static void createTransCurveVerts(TransInfo *t)
{
Curve *cu = t->obedit->data;
@@ -1513,22 +1584,22 @@ static void createTransCurveVerts(TransInfo *t)
/* to be sure */
if (cu->editnurb == NULL) return;
+#define SEL_F1 (1 << 0)
+#define SEL_F2 (1 << 1)
+#define SEL_F3 (1 << 2)
+
/* count total of vertices, check identical as in 2nd loop for making transdata! */
nurbs = BKE_curve_editNurbs_get(cu);
for (nu = nurbs->first; nu; nu = nu->next) {
if (nu->type == CU_BEZIER) {
for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
if (bezt->hide == 0) {
- if (hide_handles) {
- if (bezt->f2 & SELECT) countsel += 3;
- if (is_prop_edit) count += 3;
- }
- else {
- if (bezt->f1 & SELECT) countsel++;
- if (bezt->f2 & SELECT) countsel++;
- if (bezt->f3 & SELECT) countsel++;
- if (is_prop_edit) count += 3;
- }
+ const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
+ if (bezt_tx & SEL_F1) { countsel++; }
+ if (bezt_tx & SEL_F2) { countsel++; }
+ if (bezt_tx & SEL_F3) { countsel++; }
+ if (is_prop_edit) count += 3;
+
}
}
}
@@ -1579,10 +1650,10 @@ static void createTransCurveVerts(TransInfo *t)
}
}
- if (is_prop_edit ||
- ((bezt->f2 & SELECT) && hide_handles) ||
- ((bezt->f1 & SELECT) && hide_handles == 0))
- {
+ /* Elements that will be transform (not always a match to selection). */
+ const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
+
+ if (is_prop_edit || bezt_tx & SEL_F1) {
copy_v3_v3(td->iloc, bezt->vec[0]);
td->loc = bezt->vec[0];
copy_v3_v3(td->center, bezt->vec[(hide_handles ||
@@ -1613,7 +1684,7 @@ static void createTransCurveVerts(TransInfo *t)
}
/* This is the Curve Point, the other two are handles */
- if (is_prop_edit || (bezt->f2 & SELECT)) {
+ if (is_prop_edit || bezt_tx & SEL_F2) {
copy_v3_v3(td->iloc, bezt->vec[1]);
td->loc = bezt->vec[1];
copy_v3_v3(td->center, td->loc);
@@ -1639,7 +1710,7 @@ static void createTransCurveVerts(TransInfo *t)
copy_m3_m3(td->axismtx, axismtx);
}
- if ((bezt->f1 & SELECT) == 0 && (bezt->f3 & SELECT) == 0)
+ if ((bezt_tx & SEL_F1) == 0 && (bezt_tx & SEL_F3) == 0)
/* If the middle is selected but the sides arnt, this is needed */
if (hdata == NULL) { /* if the handle was not saved by the previous handle */
hdata = initTransDataCurveHandles(td, bezt);
@@ -1649,10 +1720,7 @@ static void createTransCurveVerts(TransInfo *t)
count++;
tail++;
}
- if (is_prop_edit ||
- ((bezt->f2 & SELECT) && hide_handles) ||
- ((bezt->f3 & SELECT) && hide_handles == 0))
- {
+ if (is_prop_edit || bezt_tx & SEL_F3) {
copy_v3_v3(td->iloc, bezt->vec[2]);
td->loc = bezt->vec[2];
copy_v3_v3(td->center, bezt->vec[(hide_handles ||
@@ -1707,6 +1775,26 @@ static void createTransCurveVerts(TransInfo *t)
for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
if (bp->hide == 0) {
if (is_prop_edit || (bp->f1 & SELECT)) {
+ float axismtx[3][3];
+
+ if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
+ if (nu->pntsv == 1) {
+ float normal[3], plane[3];
+
+ BKE_nurb_bpoint_calc_normal(nu, bp, normal);
+ BKE_nurb_bpoint_calc_plane(nu, bp, plane);
+
+ if (createSpaceNormalTangent(axismtx, normal, plane)) {
+ /* pass */
+ }
+ else {
+ normalize_v3(normal);
+ axis_dominant_v3_to_m3(axismtx, normal);
+ invert_m3(axismtx);
+ }
+ }
+ }
+
copy_v3_v3(td->iloc, bp->vec);
td->loc = bp->vec;
copy_v3_v3(td->center, td->loc);
@@ -1725,6 +1813,11 @@ static void createTransCurveVerts(TransInfo *t)
copy_m3_m3(td->smtx, smtx);
copy_m3_m3(td->mtx, mtx);
+ if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
+ if (nu->pntsv == 1) {
+ copy_m3_m3(td->axismtx, axismtx);
+ }
+ }
td++;
count++;
@@ -1740,6 +1833,10 @@ static void createTransCurveVerts(TransInfo *t)
calc_distanceCurveVerts(head, tail - 1);
}
}
+
+#undef SEL_F1
+#undef SEL_F2
+#undef SEL_F3
}
/* ********************* lattice *************** */
@@ -2004,9 +2101,9 @@ static bool bmesh_test_dist_add(
}
/**
- * \parm mtx: Measure disatnce in this space.
- * \parm dists: Store the closest connected distance to selected vertices.
- * \parm index: Optionally store the original index we're measuring the distance to (can be NULL).
+ * \param mtx: Measure disatnce in this space.
+ * \param dists: Store the closest connected distance to selected vertices.
+ * \param index: Optionally store the original index we're measuring the distance to (can be NULL).
*/
static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float *dists, int *index)
{
@@ -2276,7 +2373,7 @@ static struct TransIslandData *editmesh_islands_info_calc(
}
if (group_tot_single != 0) {
- trans_islands = MEM_reallocN(trans_islands, group_tot + group_tot_single);
+ trans_islands = MEM_reallocN(trans_islands, sizeof(*trans_islands) * (group_tot + group_tot_single));
BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
@@ -2398,7 +2495,8 @@ static void createTransEditVerts(TransInfo *t)
int island_info_tot;
int *island_vert_map = NULL;
- const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS) && (t->mode != TFM_TRANSLATION);
+ /* Even for translation this is needed because of island-orientation, see: T51651. */
+ const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS);
/* Original index of our connected vertex when connected distances are calculated.
* Optional, allocate if needed. */
int *dists_index = NULL;
@@ -2464,11 +2562,6 @@ static void createTransEditVerts(TransInfo *t)
editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index);
}
- /* Only in case of rotation and resize, we want the elements of the edited
- * object to behave as groups whose pivot are the individual origins
- *
- * TODO: use island_info to detect the closest point when the "Snap Target"
- * in Blender UI is "Closest" */
if (is_island_center) {
/* In this specific case, near-by vertices will need to know the island of the nearest connected vertex. */
const bool calc_single_islands = (
@@ -5349,7 +5442,8 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
}
/* update object's loc/rot to get current rigid body transform */
mat4_to_loc_rot_size(ob->loc, rot, scale, ob->obmat);
- BKE_object_mat3_to_rot(ob, rot, false);
+ sub_v3_v3(ob->loc, ob->dloc);
+ BKE_object_mat3_to_rot(ob, rot, false); /* drot is already corrected here */
}
}