diff options
Diffstat (limited to 'source/blender/editors/transform')
-rw-r--r-- | source/blender/editors/transform/SConscript | 28 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.c | 49 | ||||
-rw-r--r-- | source/blender/editors/transform/transform.h | 2 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 42 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_generics.c | 2 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_input.c | 5 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_manipulator.c | 105 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_orientations.c | 95 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_snap.c | 22 |
9 files changed, 243 insertions, 107 deletions
diff --git a/source/blender/editors/transform/SConscript b/source/blender/editors/transform/SConscript index 9cf36a2d970..d579fd73db3 100644 --- a/source/blender/editors/transform/SConscript +++ b/source/blender/editors/transform/SConscript @@ -1,4 +1,30 @@ -#!/usr/bin/python +#!/usr/bin/env python +# +# ***** BEGIN GPL LICENSE BLOCK ***** +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# The Original Code is Copyright (C) 2006, Blender Foundation +# All rights reserved. +# +# The Original Code is: all of this file. +# +# Contributor(s): Nathan Letwory. +# +# ***** END GPL LICENSE BLOCK ***** + Import ('env') sources = env.Glob('*.c') diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 6145fec7e51..65b29cf6475 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1585,14 +1585,17 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi /* just draw a little warning message in the top-right corner of the viewport to warn that autokeying is enabled */ static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar) { + rcti rect; const char printable[] = "Auto Keying On"; float printable_size[2]; int xco, yco; + ED_region_visible_rect(ar, &rect); + BLF_width_and_height_default(printable, &printable_size[0], &printable_size[1]); - xco = ar->winx - (int)printable_size[0] - 10; - yco = ar->winy - (int)printable_size[1] - 10; + xco = rect.xmax - (int)printable_size[0] - 10; + yco = rect.ymax - (int)printable_size[1] - 10; /* warning text (to clarify meaning of overlays) * - original color was red to match the icon, but that clashes badly with a less nasty border @@ -2579,7 +2582,8 @@ int handleEventWarp(TransInfo *t, wmEvent *event) int Warp(TransInfo *t, const int UNUSED(mval[2])) { TransData *td = t->data; - float vec[3], circumfac, dist, phi0, co, si, *curs, cursor[3], gcursor[3]; + float vec[3], circumfac, dist, phi0, co, si, cursor[3], gcursor[3]; + const float *curs; int i; char str[50]; @@ -2884,7 +2888,7 @@ BLI_INLINE int tx_vec_sign_flip(const float a[3], const float b[3]) } /* smat is reference matrix, only scaled */ -static void TransMat3ToSize(float mat[][3], float smat[][3], float size[3]) +static void TransMat3ToSize(float mat[3][3], float smat[3][3], float size[3]) { float vec[3]; @@ -4903,7 +4907,7 @@ static int createSlideVerts(TransInfo *t) BMEdge *e, *e1; BMVert *v, *v2, *first; TransDataSlideVert *sv_array; - BMBVHTree *btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL); + BMBVHTree *btree; SmallHash table; SlideData *sld = MEM_callocN(sizeof(*sld), "sld"); View3D *v3d = NULL; @@ -4915,6 +4919,7 @@ static int createSlideVerts(TransInfo *t) float vec[3], vec2[3] /*, lastvec[3], size, dis=0.0, z */ /* UNUSED */; float dir[3], maxdist, (*loop_dir)[3], *loop_maxdist; int numsel, i, j, loop_nr, l_nr; + int use_btree_disp; if (t->spacetype == SPACE_VIEW3D) { /* background mode support */ @@ -4922,6 +4927,15 @@ static int createSlideVerts(TransInfo *t) rv3d = t->ar ? t->ar->regiondata : NULL; } + use_btree_disp = (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE); + + if (use_btree_disp) { + btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL); + } + else { + btree = NULL; + } + sld->is_proportional = TRUE; sld->curr_sv_index = 0; sld->flipped_vtx = FALSE; @@ -4955,7 +4969,8 @@ static int createSlideVerts(TransInfo *t) if (numsel == 0 || numsel > 2) { MEM_freeN(sld); - BMBVH_FreeBVH(btree); + if (btree) + BMBVH_FreeBVH(btree); return 0; /* invalid edge selection */ } } @@ -4965,7 +4980,8 @@ static int createSlideVerts(TransInfo *t) if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { if (!BM_edge_is_manifold(e)) { MEM_freeN(sld); - BMBVH_FreeBVH(btree); + if (btree) + BMBVH_FreeBVH(btree); return 0; /* can only handle exactly 2 faces around each edge */ } } @@ -4985,7 +5001,8 @@ static int createSlideVerts(TransInfo *t) if (!j) { MEM_freeN(sld); - BMBVH_FreeBVH(btree); + if (btree) + BMBVH_FreeBVH(btree); return 0; } @@ -5140,9 +5157,7 @@ static int createSlideVerts(TransInfo *t) continue; /* This test is only relevant if object is not wire-drawn! See [#32068]. */ - if (v3d && t->obedit->dt > OB_WIRE && v3d->drawtype > OB_WIRE && - !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit)) - { + if (use_btree_disp && !BMBVH_EdgeVisible(btree, e2, ar, v3d, t->obedit)) { continue; } @@ -5244,10 +5259,15 @@ static int createSlideVerts(TransInfo *t) t->customData = sld; BLI_smallhash_release(&table); - BMBVH_FreeBVH(btree); + if (btree) { + BMBVH_FreeBVH(btree); + } MEM_freeN(loop_dir); MEM_freeN(loop_maxdist); - + + /* arrays are dirty from copying faces: EDBM_index_arrays_free */ + EDBM_update_generic(em, FALSE, TRUE); + return 1; } @@ -5419,6 +5439,9 @@ void freeSlideTempFaces(SlideData *sld) BLI_smallhash_release(&sld->origfaces); sld->origfaces_init = FALSE; + + /* arrays are dirty from removing faces: EDBM_index_arrays_free */ + EDBM_update_generic(sld->em, FALSE, TRUE); } } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index bc959a772d6..08fe1e7676b 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -572,7 +572,7 @@ void flushTransTracking(TransInfo *t); void flushTransMasking(TransInfo *t); /*********************** exported from transform_manipulator.c ********** */ -int gimbal_axis(struct Object *ob, float gmat[][3]); /* return 0 when no gimbal for selection */ +int gimbal_axis(struct Object *ob, float gmat[3][3]); /* return 0 when no gimbal for selection */ int calc_manipulator_stats(const struct bContext *C); /*********************** TransData Creation and General Handling *********** */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 51efa2b0e40..7da47425370 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -113,6 +113,7 @@ #include "WM_types.h" #include "UI_view2d.h" +#include "UI_interface.h" #include "RNA_access.h" @@ -271,7 +272,7 @@ static void createTransTexspace(TransInfo *t) copy_m3_m4(td->mtx, ob->obmat); copy_m3_m4(td->axismtx, ob->obmat); normalize_m3(td->axismtx); - invert_m3_m3(td->smtx, td->mtx); + pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); if (BKE_object_obdata_texspace_get(ob, &texflag, &td->loc, &td->ext->size, &td->ext->rot)) { ob->dtx |= OB_TEXSPACE; @@ -315,7 +316,7 @@ static void createTransEdge(TransInfo *t) td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransCrease"); copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); 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)) { @@ -552,7 +553,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr invert_m3_m3(td->ext->r_smtx, td->ext->r_mtx); } - invert_m3_m3(td->smtx, td->mtx); + pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); /* exceptional case: rotate the pose bone which also applies transformation * when a parentless bone has BONE_NO_LOCAL_LOCATION [] */ @@ -604,7 +605,7 @@ static void add_pose_transdata(TransInfo *t, bPoseChannel *pchan, Object *ob, Tr /* only object matrix correction */ copy_m3_m3(td->mtx, omat); - invert_m3_m3(td->smtx, td->mtx); + pseudoinverse_m3_m3(td->smtx, td->mtx, PSEUDOINVERSE_EPSILON); } } @@ -1053,7 +1054,7 @@ static void createTransArmatureVerts(TransInfo *t) if (!t->total) return; copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); td = t->data = MEM_callocN(t->total * sizeof(TransData), "TransEditBone"); @@ -1221,7 +1222,7 @@ static void createTransMBallVerts(TransInfo *t) tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension), "MetaElement_TransExtension"); copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); for (ml = mb->editelems->first; ml; ml = ml->next) { if (propmode || (ml->flag & SELECT)) { @@ -1378,7 +1379,7 @@ static void createTransCurveVerts(TransInfo *t) t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Curve EditMode)"); copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); td = t->data; for (nu = nurbs->first; nu; nu = nu->next) { @@ -1569,7 +1570,7 @@ static void createTransLatticeVerts(TransInfo *t) t->data = MEM_callocN(t->total * sizeof(TransData), "TransObData(Lattice EditMode)"); copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON); td = t->data; bp = latt->def; @@ -1769,7 +1770,7 @@ void flushTransParticles(TransInfo *t) * but instead it's a depth-first search, fudged * to report shortest distances. I have no idea how fast * or slow this is. */ -static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[][3], float *dists) +static void editmesh_set_connectivity_distance(BMEditMesh *em, float mtx[3][3], float *dists) { BMVert **queue = NULL; float *dqueue = NULL; @@ -1927,7 +1928,7 @@ static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx } else if (t->mode == TFM_SHRINKFATTEN) { td->ext = tx; - tx->isize[0] = BM_vert_calc_shell_factor(eve); + tx->isize[0] = BM_vert_calc_shell_factor_ex(eve, BM_ELEM_SELECT); } } @@ -2051,7 +2052,9 @@ static void createTransEditVerts(TransInfo *t) } copy_m3_m4(mtx, t->obedit->obmat); - invert_m3_m3(smtx, mtx); + /* 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); if (propmode & T_PROP_CONNECTED) { editmesh_set_connectivity_distance(em, mtx, dists); @@ -2195,7 +2198,12 @@ void flushTransNodes(TransInfo *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++) { bNode *node = td->extra; - add_v2_v2v2(&node->locx, td2d->loc, td2d->ih1); + float vec[2]; + + /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */ + add_v2_v2v2(vec, td2d->loc, td2d->ih1); + node->locx = vec[0] / UI_DPI_FAC; + node->locy = vec[1] / UI_DPI_FAC; } /* handle intersection with noodles */ @@ -5091,7 +5099,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) * during cleanup - psy-fi */ freeSlideTempFaces(sld); } - EDBM_automerge(t->scene, t->obedit, 1); + EDBM_automerge(t->scene, t->obedit, TRUE); } else { if (t->mode == TFM_EDGE_SLIDE) { @@ -5592,7 +5600,8 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) /* hold original location */ float locxy[2] = {BLI_rctf_cent_x(&node->totr), BLI_rctf_cent_y(&node->totr)}; - + float nodeloc[2]; + copy_v2_v2(td2d->loc, locxy); td2d->loc[2] = 0.0f; td2d->loc2d = td2d->loc; /* current location */ @@ -5617,7 +5626,10 @@ static void NodeToTransData(TransData *td, TransData2D *td2d, bNode *node) unit_m3(td->mtx); unit_m3(td->smtx); - sub_v2_v2v2(td2d->ih1, &node->locx, locxy); + /* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */ + nodeloc[0] = UI_DPI_FAC * node->locx; + nodeloc[1] = UI_DPI_FAC * node->locy; + sub_v2_v2v2(td2d->ih1, nodeloc, locxy); td->extra = node; } diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c index 615bb786071..6d7ddd4e0ed 100644 --- a/source/blender/editors/transform/transform_generics.c +++ b/source/blender/editors/transform/transform_generics.c @@ -1445,7 +1445,7 @@ void calculateCenter2D(TransInfo *t) void calculateCenterCursor(TransInfo *t) { - float *cursor; + const float *cursor; cursor = give_cursor(t->scene, t->view); copy_v3_v3(t->center, cursor); diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c index 7e05fdae364..69569251d01 100644 --- a/source/blender/editors/transform/transform_input.c +++ b/source/blender/editors/transform/transform_input.c @@ -397,12 +397,13 @@ int handleMouseInput(TransInfo *t, MouseInput *mi, wmEvent *event) * store the mouse position where the normal movement ended */ copy_v2_v2_int(mi->precision_mval, event->mval); mi->precision = 1; + redraw = TREDRAW_HARD; } - else { + else if (event->val == KM_RELEASE) { t->modifiers &= ~MOD_PRECISION; mi->precision = 0; + redraw = TREDRAW_HARD; } - redraw = TREDRAW_HARD; break; } diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index a3f45acc02e..6b016bf4303 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -148,10 +148,8 @@ static void stats_pose(Scene *scene, RegionView3D *rv3d, bPoseChannel *pchan) Bone *bone = pchan->bone; if (bone) { - if (bone->flag & BONE_TRANSFORM) { - calc_tw_center(scene, pchan->pose_head); - protectflag_to_drawflags(pchan->protectflag, &rv3d->twdrawflag); - } + calc_tw_center(scene, pchan->pose_head); + protectflag_to_drawflags(pchan->protectflag, &rv3d->twdrawflag); } } @@ -199,7 +197,7 @@ static int test_rotmode_euler(short rotmode) return (ELEM(rotmode, ROT_MODE_AXISANGLE, ROT_MODE_QUAT)) ? 0 : 1; } -int gimbal_axis(Object *ob, float gmat[][3]) +int gimbal_axis(Object *ob, float gmat[3][3]) { if (ob) { if (ob->mode & OB_MODE_POSE) { @@ -361,18 +359,35 @@ int calc_manipulator_stats(const bContext *C) else if (obedit->type == OB_ARMATURE) { bArmature *arm = obedit->data; EditBone *ebo; - for (ebo = arm->edbo->first; ebo; ebo = ebo->next) { - if (EBONE_VISIBLE(arm, ebo)) { - if (ebo->flag & BONE_TIPSEL) { - calc_tw_center(scene, ebo->tail); - totsel++; - } - if (ebo->flag & BONE_ROOTSEL) { - calc_tw_center(scene, ebo->head); - totsel++; - } - if (ebo->flag & BONE_SELECTED) { - stats_editbone(rv3d, ebo); + + if ((v3d->around == V3D_ACTIVE) && (ebo = arm->act_edbone)) { + /* doesn't check selection or visibility intentionally */ + if (ebo->flag & BONE_TIPSEL) { + calc_tw_center(scene, ebo->tail); + totsel++; + } + if ((ebo->flag & BONE_ROOTSEL) || + ((ebo->flag & BONE_TIPSEL) == FALSE)) /* ensure we get at least one point */ + { + calc_tw_center(scene, ebo->head); + totsel++; + } + stats_editbone(rv3d, ebo); + } + else { + for (ebo = arm->edbo->first; ebo; ebo = ebo->next) { + if (EBONE_VISIBLE(arm, ebo)) { + if (ebo->flag & BONE_TIPSEL) { + calc_tw_center(scene, ebo->tail); + totsel++; + } + if (ebo->flag & BONE_ROOTSEL) { + calc_tw_center(scene, ebo->head); + totsel++; + } + if (ebo->flag & BONE_SELECTED) { + stats_editbone(rv3d, ebo); + } } } } @@ -480,17 +495,35 @@ int calc_manipulator_stats(const bContext *C) else if (ob && (ob->mode & OB_MODE_POSE)) { bPoseChannel *pchan; int mode = TFM_ROTATION; // mislead counting bones... bah. We don't know the manipulator mode, could be mixed + int ok = FALSE; if ((ob->lay & v3d->lay) == 0) return 0; - totsel = count_set_pose_transflags(&mode, 0, ob); - - if (totsel) { - /* use channels to get stats */ - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + if ((v3d->around == V3D_ACTIVE) && (pchan = BKE_pose_channel_active(ob))) { + /* doesn't check selection or visibility intentionally */ + Bone *bone = pchan->bone; + if (bone) { stats_pose(scene, rv3d, pchan); + totsel = 1; + ok = TRUE; + } + } + else { + totsel = count_set_pose_transflags(&mode, 0, ob); + + if (totsel) { + /* use channels to get stats */ + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + Bone *bone = pchan->bone; + if (bone && (bone->flag & BONE_TRANSFORM)) { + stats_pose(scene, rv3d, pchan); + } + } + ok = TRUE; } + } + if (ok) { mul_v3_fl(scene->twcent, 1.0f / (float)totsel); // centroid! mul_m4_v3(ob->obmat, scene->twcent); mul_m4_v3(ob->obmat, scene->twmin); @@ -552,8 +585,9 @@ int calc_manipulator_stats(const bContext *C) switch (v3d->twmode) { case V3D_MANIP_GLOBAL: + { break; /* nothing to do */ - + } case V3D_MANIP_GIMBAL: { float mat[3][3]; @@ -562,28 +596,43 @@ int calc_manipulator_stats(const bContext *C) break; } /* if not gimbal, fall through to normal */ + /* pass through */ } case V3D_MANIP_NORMAL: + { if (obedit || ob->mode & OB_MODE_POSE) { float mat[3][3]; ED_getTransformOrientationMatrix(C, mat, (v3d->around == V3D_ACTIVE)); copy_m4_m3(rv3d->twmat, mat); break; } - /* no break we define 'normal' as 'local' in Object mode */ + /* no break we define 'normal' as 'local' in Object mode */ + /* pass through */ + } case V3D_MANIP_LOCAL: + { + if (ob->mode & OB_MODE_POSE) { + /* each bone moves on its own local axis, but to avoid confusion, + * use the active pones axis for display [#33575], this works as expected on a single bone + * and users who select many bones will understand whats going on and what local means + * when they start transforming */ + float mat[3][3]; + ED_getTransformOrientationMatrix(C, mat, (v3d->around == V3D_ACTIVE)); + copy_m4_m3(rv3d->twmat, mat); + break; + } copy_m4_m4(rv3d->twmat, ob->obmat); normalize_m4(rv3d->twmat); break; - + } case V3D_MANIP_VIEW: { float mat[3][3]; copy_m3_m4(mat, rv3d->viewinv); normalize_m3(mat); copy_m4_m3(rv3d->twmat, mat); + break; } - break; default: /* V3D_MANIP_CUSTOM */ { float mat[3][3]; @@ -638,7 +687,7 @@ static void test_manipulator_axis(const bContext *C) /* ******************** DRAWING STUFFIES *********** */ -static float screen_aligned(RegionView3D *rv3d, float mat[][4]) +static float screen_aligned(RegionView3D *rv3d, float mat[4][4]) { glTranslatef(mat[3][0], mat[3][1], mat[3][2]); @@ -826,7 +875,7 @@ static void draw_manipulator_axes(View3D *v3d, RegionView3D *rv3d, int colcode, } } -static void preOrthoFront(int ortho, float twmat[][4], int axis) +static void preOrthoFront(int ortho, float twmat[4][4], int axis) { if (ortho == 0) { float omat[4][4]; diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 70e4d4cd027..c9c4f7e2c7b 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -43,6 +43,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BKE_action.h" #include "BKE_armature.h" #include "BKE_curve.h" #include "BKE_context.h" @@ -437,7 +438,7 @@ int BIF_countTransformOrientation(const bContext *C) return count; } -void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) +void applyTransformOrientation(const bContext *C, float mat[3][3], char name[MAX_NAME]) { TransformOrientation *ts; View3D *v3d = CTX_wm_view3d(C); @@ -448,8 +449,9 @@ void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) for (i = 0, ts = CTX_data_scene(C)->transform_spaces.first; ts; ts = ts->next, i++) { if (selected_index == i) { - if (name) - strcpy(name, ts->name); + if (name) { + BLI_strncpy(name, ts->name, MAX_NAME); + } copy_m3_m3(mat, ts->mat); break; @@ -737,7 +739,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], } } - if (normal[0] != 0 || normal[1] != 0 || normal[2] != 0) { + if (!is_zero_v3(normal)) { result = ORIENTATION_NORMAL; } } @@ -760,29 +762,45 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], else if (obedit->type == OB_ARMATURE) { bArmature *arm = obedit->data; EditBone *ebone; + int ok = FALSE; - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (arm->layer & ebone->layer) { - if (ebone->flag & BONE_SELECTED) { - float tmat[3][3]; - float vec[3]; - sub_v3_v3v3(vec, ebone->tail, ebone->head); - normalize_v3(vec); - add_v3_v3(normal, vec); - - vec_roll_to_mat3(vec, ebone->roll, tmat); - add_v3_v3(plane, tmat[2]); + /* grr,.but better then duplicate code */ +#define EBONE_CALC_NORMAL_PLANE { \ + float tmat[3][3]; \ + float vec[3]; \ + sub_v3_v3v3(vec, ebone->tail, ebone->head); \ + normalize_v3(vec); \ + add_v3_v3(normal, vec); \ + \ + vec_roll_to_mat3(vec, ebone->roll, tmat); \ + add_v3_v3(plane, tmat[2]); \ + } (void)0 + + + if (activeOnly && (ebone = arm->act_edbone)) { + EBONE_CALC_NORMAL_PLANE; + ok = TRUE; + } + else { + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (arm->layer & ebone->layer) { + if (ebone->flag & BONE_SELECTED) { + EBONE_CALC_NORMAL_PLANE; + ok = TRUE; + } } } } - normalize_v3(normal); - normalize_v3(plane); + if (ok) { + normalize_v3(normal); + normalize_v3(plane); - if (plane[0] != 0 || plane[1] != 0 || plane[2] != 0) { - result = ORIENTATION_EDGE; + if (!is_zero_v3(plane)) { + result = ORIENTATION_EDGE; + } } - +#undef EBONE_CALC_NORMAL_PLANE } /* Vectors from edges don't need the special transpose inverse multiplication */ @@ -798,19 +816,32 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], else if (ob && (ob->mode & OB_MODE_POSE)) { bArmature *arm = ob->data; bPoseChannel *pchan; - int totsel; - - totsel = count_bone_select(arm, &arm->bonebase, 1); - if (totsel) { - float imat[3][3], mat[3][3]; - - /* use channels to get stats */ - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) { - add_v3_v3(normal, pchan->pose_mat[2]); - add_v3_v3(plane, pchan->pose_mat[1]); + float imat[3][3], mat[3][3]; + int ok = FALSE; + + if (activeOnly && (pchan = BKE_pose_channel_active(ob))) { + add_v3_v3(normal, pchan->pose_mat[2]); + add_v3_v3(plane, pchan->pose_mat[1]); + ok = TRUE; + } + else { + int totsel; + + totsel = count_bone_select(arm, &arm->bonebase, 1); + if (totsel) { + /* use channels to get stats */ + for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { + if (pchan->bone && pchan->bone->flag & BONE_TRANSFORM) { + add_v3_v3(normal, pchan->pose_mat[2]); + add_v3_v3(plane, pchan->pose_mat[1]); + } } + ok = TRUE; } + } + + /* use for both active & all */ + if (ok) { negate_v3(plane); /* we need the transpose of the inverse for a normal... */ @@ -851,7 +882,7 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], return result; } -void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[][3], int activeOnly) +void ED_getTransformOrientationMatrix(const bContext *C, float orientation_mat[3][3], int activeOnly) { float normal[3] = {0.0, 0.0, 0.0}; float plane[3] = {0.0, 0.0, 0.0}; diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 2d95e2ecdc6..5577619901a 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1141,7 +1141,7 @@ static void TargetSnapClosest(TransInfo *t) } } -static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float obmat[][4], float timat[][3], +static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], short v2no[3], float obmat[4][4], float timat[3][3], const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2], float r_loc[3], float r_no[3], int *r_dist, float *r_depth) { @@ -1228,7 +1228,7 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh return retval; } -static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4], float timat[][3], +static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[4][4], float timat[3][3], const float ray_start[3], const float ray_start_local[3], const float ray_normal_local[3], const float mval[2], float r_loc[3], float r_no[3], int *r_dist, float *r_depth) { @@ -1276,7 +1276,7 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4], return retval; } -static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[][4], +static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm, float obmat[4][4], const float ray_start[3], const float ray_normal[3], const float mval[2], float r_loc[3], float *UNUSED(r_no), int *r_dist, float *r_depth) { @@ -1339,7 +1339,7 @@ static int snapArmature(short snap_mode, ARegion *ar, Object *ob, bArmature *arm return retval; } -static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[][4], +static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh *dm, BMEditMesh *em, float obmat[4][4], const float ray_start[3], const float ray_normal[3], const float mval[2], float r_loc[3], float r_no[3], int *r_dist, float *r_depth) { @@ -1417,7 +1417,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh if (em != NULL) { index_array = dm->getVertDataArray(dm, CD_ORIGINDEX); - EDBM_index_arrays_init(em, 1, 0, 0); + EDBM_index_arrays_ensure(em, BM_VERT); } for (i = 0; i < totvert; i++) { @@ -1452,9 +1452,6 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh } } - if (em != NULL) { - EDBM_index_arrays_free(em); - } break; } case SCE_SNAP_MODE_EDGE: @@ -1468,7 +1465,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh if (em != NULL) { index_array = dm->getEdgeDataArray(dm, CD_ORIGINDEX); - EDBM_index_arrays_init(em, 0, 1, 0); + EDBM_index_arrays_ensure(em, BM_EDGE); } for (i = 0; i < totedge; i++) { @@ -1505,9 +1502,6 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh } } - if (em != NULL) { - EDBM_index_arrays_free(em); - } break; } } @@ -1517,7 +1511,7 @@ static int snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMesh return retval; } -static int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[][4], +static int snapObject(Scene *scene, ARegion *ar, Object *ob, int editobject, float obmat[4][4], const float ray_start[3], const float ray_normal[3], const float mval[2], float r_loc[3], float r_no[3], int *r_dist, float *r_depth) { @@ -1670,7 +1664,7 @@ static void addDepthPeel(ListBase *depth_peels, float depth, float p[3], float n peel->flag = 0; } -static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], +static int peelDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[4][4], const float ray_start[3], const float ray_normal[3], const float UNUSED(mval[2]), ListBase *depth_peels) { |