From 663c800ef3198e6a2f7857e0dd2794690e977eda Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 9 May 2014 16:52:09 +1000 Subject: Fix T36973: Active snapping fails for edges/faces also add snap-active support for armatures, pose & metas --- source/blender/editors/transform/transform.c | 2 +- source/blender/editors/transform/transform.h | 16 +- .../editors/transform/transform_conversions.c | 24 +-- .../blender/editors/transform/transform_generics.c | 199 +++++++++++++-------- source/blender/editors/transform/transform_snap.c | 21 +-- 5 files changed, 142 insertions(+), 120 deletions(-) (limited to 'source/blender/editors/transform') diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 7cdc329cdc6..5667b774b71 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2770,7 +2770,7 @@ static void initBend(TransInfo *t) t->flag |= T_NO_CONSTRAINT; //copy_v3_v3(t->center, ED_view3d_cursor3d_get(t->scene, t->view)); - calculateCenterCursor(t); + calculateCenterCursor(t, t->center); t->val = 0.0f; diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 0451238058a..f34d2050853 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -461,7 +461,6 @@ typedef struct TransInfo { /* transdata->flag */ #define TD_SELECTED 1 -#define TD_ACTIVE (1 << 1) #define TD_NOACTION (1 << 2) #define TD_USEQUAT (1 << 3) #define TD_NOTCONNECTED (1 << 4) @@ -636,13 +635,18 @@ void applyTransObjects(TransInfo *t); void restoreTransObjects(TransInfo *t); void recalcData(TransInfo *t); -void calculateCenter(TransInfo *t); void calculateCenter2D(TransInfo *t); -void calculateCenterBound(TransInfo *t); -void calculateCenterMedian(TransInfo *t); -void calculateCenterCursor(TransInfo *t); -void calculateCenterCursor2D(TransInfo *t); +void calculateCenter(TransInfo *t); + +/* API functions for getting center points */ +void calculateCenterBound(TransInfo *t, float r_center[3]); +void calculateCenterMedian(TransInfo *t, float r_center[3]); +void calculateCenterCursor(TransInfo *t, float r_center[3]); +void calculateCenterCursor2D(TransInfo *t, float r_center[2]); +void calculateCenterCursorGraph2D(TransInfo *t, float r_center[2]); +bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]); + void calculatePropRatio(TransInfo *t); void getViewVector(TransInfo *t, float coord[3], float vec[3]); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 91f0623e865..949ee79a3dc 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1612,7 +1612,7 @@ static void createTransLatticeVerts(TransInfo *t) { Lattice *latt = ((Lattice *)t->obedit->data)->editlatt->latt; TransData *td = NULL; - BPoint *bp, *actbp = BKE_lattice_active_point_get(latt); + BPoint *bp; float mtx[3][3], smtx[3][3]; int a; int count = 0, countsel = 0; @@ -1649,7 +1649,6 @@ static void createTransLatticeVerts(TransInfo *t) copy_v3_v3(td->center, td->loc); if (bp->f1 & SELECT) { td->flag = TD_SELECTED; - if (actbp && bp == actbp) td->flag |= TD_ACTIVE; } else td->flag = 0; copy_m3_m3(td->smtx, smtx); @@ -2138,7 +2137,6 @@ static void createTransEditVerts(TransInfo *t) BMesh *bm = em->bm; BMVert *eve; BMIter iter; - BMVert *eve_act = NULL; float (*mappedcos)[3] = NULL, (*quats)[4] = NULL; float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL; float *dists = NULL; @@ -2178,10 +2176,6 @@ static void createTransEditVerts(TransInfo *t) BLI_assert(0); } - - /* check active */ - eve_act = BM_mesh_active_vert_get(bm); - if (t->mode == TFM_BWEIGHT) { BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(t->obedit), ME_CDFLAG_VERT_BWEIGHT); cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); @@ -2287,9 +2281,6 @@ static void createTransEditVerts(TransInfo *t) if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) tob->flag |= TD_SELECTED; - /* active */ - if (eve == eve_act) tob->flag |= TD_ACTIVE; - if (propmode) { if (propmode & T_PROP_CONNECTED) { tob->dist = dists[a]; @@ -4726,8 +4717,7 @@ static bool constraints_list_needinv(TransInfo *t, ListBase *list) } /* transcribe given object into TransData for Transforming */ -static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob, - const Object *ob_act) +static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob) { Scene *scene = t->scene; bool constinv; @@ -4851,11 +4841,6 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob, unit_m3(td->smtx); unit_m3(td->mtx); } - - /* set active flag */ - if (ob == ob_act) { - td->flag |= TD_ACTIVE; - } } @@ -5863,7 +5848,6 @@ int special_transform_moving(TransInfo *t) static void createTransObject(bContext *C, TransInfo *t) { Scene *scene = t->scene; - const Object *ob_act = OBACT; TransData *td = NULL; TransDataExtension *tx; @@ -5906,7 +5890,7 @@ static void createTransObject(bContext *C, TransInfo *t) td->flag |= TD_SKIP; } - ObjectToTransData(t, td, ob, ob_act); + ObjectToTransData(t, td, ob); td->val = NULL; td++; tx++; @@ -5928,7 +5912,7 @@ static void createTransObject(bContext *C, TransInfo *t) td->ext = tx; td->ext->rotOrder = ob->rotmode; - ObjectToTransData(t, td, ob, ob_act); + ObjectToTransData(t, td, ob); td->val = NULL; td++; tx++; diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 632d6c0eba0..f813db04205 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -49,6 +49,7 @@ #include "DNA_modifier_types.h" #include "DNA_movieclip_types.h" #include "DNA_mask_types.h" +#include "DNA_meta_types.h" #include "BLI_math.h" #include "BLI_blenlib.h" @@ -1518,28 +1519,26 @@ void calculateCenter2D(TransInfo *t) } } -void calculateCenterCursor(TransInfo *t) +void calculateCenterCursor(TransInfo *t, float r_center[3]) { const float *cursor; cursor = ED_view3d_cursor3d_get(t->scene, t->view); - copy_v3_v3(t->center, cursor); + copy_v3_v3(r_center, cursor); /* If edit or pose mode, move cursor in local space */ if (t->flag & (T_EDIT | T_POSE)) { Object *ob = t->obedit ? t->obedit : t->poseobj; float mat[3][3], imat[3][3]; - sub_v3_v3v3(t->center, t->center, ob->obmat[3]); + sub_v3_v3v3(r_center, r_center, ob->obmat[3]); copy_m3_m4(mat, ob->obmat); invert_m3_m3(imat, mat); - mul_m3_v3(imat, t->center); + mul_m3_v3(imat, r_center); } - - calculateCenter2D(t); } -void calculateCenterCursor2D(TransInfo *t) +void calculateCenterCursor2D(TransInfo *t, float r_center[2]) { float aspx = 1.0, aspy = 1.0; const float *cursor = NULL; @@ -1586,31 +1585,27 @@ void calculateCenterCursor2D(TransInfo *t) BLI_assert(!"Shall not happen"); } - t->center[0] = co[0] * aspx; - t->center[1] = co[1] * aspy; + r_center[0] = co[0] * aspx; + r_center[1] = co[1] * aspy; } else { - t->center[0] = cursor[0] * aspx; - t->center[1] = cursor[1] * aspy; + r_center[0] = cursor[0] * aspx; + r_center[1] = cursor[1] * aspy; } } - - calculateCenter2D(t); } -static void calculateCenterCursorGraph2D(TransInfo *t) +void calculateCenterCursorGraph2D(TransInfo *t, float r_center[2]) { SpaceIpo *sipo = (SpaceIpo *)t->sa->spacedata.first; Scene *scene = t->scene; /* cursor is combination of current frame, and graph-editor cursor value */ - t->center[0] = (float)(scene->r.cfra); - t->center[1] = sipo->cursorVal; - - calculateCenter2D(t); + r_center[0] = (float)(scene->r.cfra); + r_center[1] = sipo->cursorVal; } -void calculateCenterMedian(TransInfo *t) +void calculateCenterMedian(TransInfo *t, float r_center[3]) { float partial[3] = {0.0f, 0.0f, 0.0f}; int total = 0; @@ -1626,12 +1621,10 @@ void calculateCenterMedian(TransInfo *t) } if (i) mul_v3_fl(partial, 1.0f / total); - copy_v3_v3(t->center, partial); - - calculateCenter2D(t); + copy_v3_v3(r_center, partial); } -void calculateCenterBound(TransInfo *t) +void calculateCenterBound(TransInfo *t, float r_center[3]) { float max[3]; float min[3]; @@ -1648,83 +1641,137 @@ void calculateCenterBound(TransInfo *t) copy_v3_v3(min, t->data[i].center); } } - mid_v3_v3v3(t->center, min, max); + mid_v3_v3v3(r_center, min, max); +} - calculateCenter2D(t); +/** + * \param select_only only get active center from data being transformed. + */ +bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3]) +{ + bool ok = false; + + if (t->obedit) { + switch (t->obedit->type) { + case OB_MESH: + { + BMEditSelection ese; + BMEditMesh *em = BKE_editmesh_from_object(t->obedit); + + if (BM_select_history_active_get(em->bm, &ese)) { + BM_editselection_center(&ese, r_center); + ok = true; + } + break; + } + case OB_ARMATURE: + { + bArmature *arm = t->obedit->data; + EditBone *ebo = arm->act_edbone; + + if (ebo && (!select_only || (ebo->flag & (BONE_SELECTED | BONE_ROOTSEL)))) { + copy_v3_v3(r_center, ebo->head); + ok = true; + } + + break; + } + case OB_CURVE: + case OB_SURF: + { + float center[3]; + Curve *cu = (Curve *)t->obedit->data; + + if (ED_curve_active_center(cu, center)) { + copy_v3_v3(r_center, center); + ok = true; + } + break; + } + case OB_MBALL: + { + MetaBall *mb = (MetaBall *)t->obedit->data; + MetaElem *ml_act = mb->lastelem; + + if (ml_act && (!select_only || (ml_act->flag & SELECT))) { + copy_v3_v3(r_center, &ml_act->x); + ok = true; + } + break; + } + case OB_LATTICE: + { + BPoint *actbp = BKE_lattice_active_point_get(t->obedit->data); + + if (actbp) { + copy_v3_v3(r_center, actbp->vec); + ok = true; + } + break; + } + } + } + else if (t->flag & T_POSE) { + Scene *scene = t->scene; + Object *ob = OBACT; + if (ob) { + bPoseChannel *pchan = BKE_pose_channel_active(ob); + if (pchan && (!select_only || (pchan->bone->flag & BONE_SELECTED))) { + copy_v3_v3(r_center, pchan->pose_head); + ok = true; + } + } + } + else { + /* object mode */ + Scene *scene = t->scene; + Object *ob = OBACT; + if (ob && (!select_only || (ob->flag & SELECT))) { + copy_v3_v3(r_center, ob->obmat[3]); + ok = true; + } + } + + return ok; } + void calculateCenter(TransInfo *t) { switch (t->around) { case V3D_CENTER: - calculateCenterBound(t); + calculateCenterBound(t, t->center); break; case V3D_CENTROID: - calculateCenterMedian(t); + calculateCenterMedian(t, t->center); break; case V3D_CURSOR: if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP)) - calculateCenterCursor2D(t); + calculateCenterCursor2D(t, t->center); else if (t->spacetype == SPACE_IPO) - calculateCenterCursorGraph2D(t); + calculateCenterCursorGraph2D(t, t->center); else - calculateCenterCursor(t); + calculateCenterCursor(t, t->center); break; case V3D_LOCAL: /* Individual element center uses median center for helpline and such */ - calculateCenterMedian(t); + calculateCenterMedian(t, t->center); break; case V3D_ACTIVE: { - /* set median, and if if if... do object center */ - - /* EDIT MODE ACTIVE EDITMODE ELEMENT */ - - if (t->obedit) { - if (t->obedit && t->obedit->type == OB_MESH) { - BMEditSelection ese; - BMEditMesh *em = BKE_editmesh_from_object(t->obedit); - - if (BM_select_history_active_get(em->bm, &ese)) { - BM_editselection_center(&ese, t->center); - calculateCenter2D(t); - break; - } - } - else if (ELEM(t->obedit->type, OB_CURVE, OB_SURF)) { - float center[3]; - Curve *cu = (Curve *)t->obedit->data; - - if (ED_curve_active_center(cu, center)) { - copy_v3_v3(t->center, center); - calculateCenter2D(t); - break; - } - } - else if (t->obedit && t->obedit->type == OB_LATTICE) { - BPoint *actbp = BKE_lattice_active_point_get(t->obedit->data); - - if (actbp) { - copy_v3_v3(t->center, actbp->vec); - calculateCenter2D(t); - break; - } - } - } /* END EDIT MODE ACTIVE ELEMENT */ - - calculateCenterMedian(t); - if ((t->flag & (T_EDIT | T_POSE)) == 0) { - Scene *scene = t->scene; - Object *ob = OBACT; - if (ob) { - copy_v3_v3(t->center, ob->obmat[3]); - projectFloatView(t, t->center, t->center2d); - } + if (calculateCenterActive(t, false, t->center)) { + /* pass */ + } + else { + /* fallback */ + calculateCenterMedian(t, t->center); } break; } } - + + calculateCenter2D(t); + /* setting constraint center */ copy_v3_v3(t->con.center, t->center); if (t->flag & (T_EDIT | T_POSE)) { diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 055dd5fbf87..9afc12a5270 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1091,27 +1091,14 @@ static void TargetSnapActive(TransInfo *t) { /* Only need to calculate once */ if ((t->tsnap.status & TARGET_INIT) == 0) { - TransData *td = NULL; - TransData *active_td = NULL; - int i; - - for (td = t->data, i = 0; i < t->total && td->flag & TD_SELECTED; i++, td++) { - if (td->flag & TD_ACTIVE) { - active_td = td; - break; - } - } - - if (active_td) { - copy_v3_v3(t->tsnap.snapTarget, active_td->center); - + if (calculateCenterActive(t, true, t->tsnap.snapTarget)) { if (t->flag & (T_EDIT | T_POSE)) { Object *ob = t->obedit ? t->obedit : t->poseobj; mul_m4_v3(ob->obmat, t->tsnap.snapTarget); } - - TargetSnapOffset(t, active_td); - + + TargetSnapOffset(t, NULL); + t->tsnap.status |= TARGET_INIT; } /* No active, default to median */ -- cgit v1.2.3