2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2009-03-01 06:36:16 +00:00
|
|
|
* ***** 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,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2009-03-01 06:36:16 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* The Original Code is: all of this file.
|
|
|
|
*
|
|
|
|
* Contributor(s): none yet.
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
2011-02-27 20:29:51 +00:00
|
|
|
/** \file blender/editors/space_view3d/view3d_snap.c
|
|
|
|
* \ingroup spview3d
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2009-03-01 06:36:16 +00:00
|
|
|
#include <math.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
#include "DNA_armature_types.h"
|
|
|
|
#include "DNA_curve_types.h"
|
|
|
|
#include "DNA_lattice_types.h"
|
2012-02-19 22:17:30 +00:00
|
|
|
#include "DNA_mesh_types.h"
|
2009-03-01 06:36:16 +00:00
|
|
|
#include "DNA_meta_types.h"
|
|
|
|
#include "DNA_scene_types.h"
|
2010-08-04 04:01:27 +00:00
|
|
|
#include "DNA_object_types.h"
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
2009-11-10 20:43:45 +00:00
|
|
|
#include "BLI_math.h"
|
2009-03-01 06:36:16 +00:00
|
|
|
#include "BLI_linklist.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
#include "BKE_armature.h"
|
2010-08-01 12:47:49 +00:00
|
|
|
#include "BKE_context.h"
|
2009-03-01 06:36:16 +00:00
|
|
|
#include "BKE_curve.h"
|
|
|
|
#include "BKE_depsgraph.h"
|
|
|
|
#include "BKE_lattice.h"
|
2010-08-01 12:47:49 +00:00
|
|
|
#include "BKE_main.h"
|
2009-03-01 06:36:16 +00:00
|
|
|
#include "BKE_object.h"
|
2013-04-13 20:31:52 +00:00
|
|
|
#include "BKE_editmesh.h"
|
2011-04-15 02:45:02 +00:00
|
|
|
#include "BKE_DerivedMesh.h"
|
2011-12-15 16:10:49 +00:00
|
|
|
#include "BKE_scene.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
#include "BKE_tracking.h"
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
#include "WM_api.h"
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "ED_armature.h"
|
|
|
|
#include "ED_mesh.h"
|
2011-10-10 12:56:21 +00:00
|
|
|
#include "ED_keyframing.h"
|
2009-03-01 06:36:16 +00:00
|
|
|
#include "ED_screen.h"
|
2011-09-14 00:37:27 +00:00
|
|
|
#include "ED_curve.h" /* for curve_editnurbs */
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
#include "view3d_intern.h"
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
extern float originmat[3][3]; /* XXX object.c */
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* ************************************************** */
|
|
|
|
/* ********************* old transform stuff ******** */
|
|
|
|
/* *********** will get replaced with new transform * */
|
|
|
|
/* ************************************************** */
|
|
|
|
|
|
|
|
typedef struct TransVert {
|
|
|
|
float *loc;
|
2012-11-05 10:33:59 +00:00
|
|
|
float oldloc[3], maploc[3];
|
2009-03-01 06:36:16 +00:00
|
|
|
float *val, oldval;
|
|
|
|
int flag;
|
|
|
|
} TransVert;
|
|
|
|
|
2012-02-03 02:36:03 +00:00
|
|
|
/* SELECT == (1 << 0) */
|
|
|
|
#define TX_VERT_USE_MAPLOC (1 << 1)
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
static TransVert *transvmain = NULL;
|
|
|
|
static int tottrans = 0;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* copied from editobject.c, now uses (almost) proper depgraph */
|
2010-10-15 12:29:02 +00:00
|
|
|
static void special_transvert_update(Object *obedit)
|
2009-03-01 06:36:16 +00:00
|
|
|
{
|
2012-02-22 16:52:06 +00:00
|
|
|
if (obedit) {
|
2011-01-03 12:41:16 +00:00
|
|
|
DAG_id_tag_update(obedit->data, 0);
|
2009-02-14 13:07:09 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (obedit->type == OB_MESH) {
|
2013-04-16 05:59:48 +00:00
|
|
|
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
2013-04-24 12:07:13 +00:00
|
|
|
BM_mesh_normals_update(em->bm);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
Curve *cu = obedit->data;
|
2012-04-28 16:49:00 +00:00
|
|
|
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
|
2012-03-25 23:54:33 +00:00
|
|
|
Nurb *nu = nurbs->first;
|
2010-07-25 11:57:36 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
while (nu) {
|
2010-09-25 06:45:28 +00:00
|
|
|
/* keep handles' vectors unchanged */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (nu->bezt) {
|
2012-03-25 23:54:33 +00:00
|
|
|
int a = nu->pntsu;
|
|
|
|
TransVert *tv = transvmain;
|
|
|
|
BezTriple *bezt = nu->bezt;
|
2010-09-25 06:45:28 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
while (a--) {
|
|
|
|
if (bezt->f1 & SELECT) tv++;
|
2010-09-25 06:45:28 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (bezt->f2 & SELECT) {
|
2010-09-25 06:45:28 +00:00
|
|
|
float v[3];
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (bezt->f1 & SELECT) {
|
2012-03-25 23:54:33 +00:00
|
|
|
sub_v3_v3v3(v, (tv - 1)->oldloc, tv->oldloc);
|
2010-09-25 06:45:28 +00:00
|
|
|
add_v3_v3v3(bezt->vec[0], bezt->vec[1], v);
|
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (bezt->f3 & SELECT) {
|
2012-03-25 23:54:33 +00:00
|
|
|
sub_v3_v3v3(v, (tv + 1)->oldloc, tv->oldloc);
|
2010-09-25 06:45:28 +00:00
|
|
|
add_v3_v3v3(bezt->vec[2], bezt->vec[1], v);
|
|
|
|
}
|
|
|
|
|
|
|
|
tv++;
|
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (bezt->f3 & SELECT) tv++;
|
2010-09-25 06:45:28 +00:00
|
|
|
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-04-28 16:49:00 +00:00
|
|
|
BKE_nurb_test2D(nu);
|
|
|
|
BKE_nurb_handles_test(nu); /* test for bezier too */
|
2012-03-25 23:54:33 +00:00
|
|
|
nu = nu->next;
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (obedit->type == OB_ARMATURE) {
|
|
|
|
bArmature *arm = obedit->data;
|
2009-03-01 06:36:16 +00:00
|
|
|
EditBone *ebo;
|
2012-03-25 23:54:33 +00:00
|
|
|
TransVert *tv = transvmain;
|
|
|
|
int a = 0;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* Ensure all bone tails are correctly adjusted */
|
2012-03-25 23:54:33 +00:00
|
|
|
for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
|
2009-03-01 06:36:16 +00:00
|
|
|
/* adjust tip if both ends selected */
|
|
|
|
if ((ebo->flag & BONE_ROOTSEL) && (ebo->flag & BONE_TIPSEL)) {
|
|
|
|
if (tv) {
|
|
|
|
float diffvec[3];
|
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
sub_v3_v3v3(diffvec, tv->loc, tv->oldloc);
|
2010-04-21 12:27:48 +00:00
|
|
|
add_v3_v3(ebo->tail, diffvec);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
a++;
|
2012-03-25 23:54:33 +00:00
|
|
|
if (a < tottrans) tv++;
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Ensure all bones are correctly adjusted */
|
2012-03-25 23:54:33 +00:00
|
|
|
for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if ((ebo->flag & BONE_CONNECTED) && ebo->parent) {
|
2009-03-01 06:36:16 +00:00
|
|
|
/* If this bone has a parent tip that has been moved */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ebo->parent->flag & BONE_TIPSEL) {
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(ebo->head, ebo->parent->tail);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
/* If this bone has a parent tip that has NOT been moved */
|
2012-03-24 06:38:07 +00:00
|
|
|
else {
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(ebo->parent->tail, ebo->head);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (arm->flag & ARM_MIRROR_EDIT)
|
2009-03-01 06:36:16 +00:00
|
|
|
transform_armature_mirror_update(obedit);
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (obedit->type == OB_LATTICE) {
|
|
|
|
Lattice *lt = obedit->data;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (lt->editlatt->latt->flag & LT_OUTSIDE)
|
2010-08-10 06:36:42 +00:00
|
|
|
outside_lattice(lt->editlatt->latt);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-05 10:33:59 +00:00
|
|
|
/* currently only used for bmesh index values */
|
|
|
|
enum {
|
|
|
|
TM_INDEX_ON = 1, /* tag to make trans verts */
|
|
|
|
TM_INDEX_OFF = 0, /* don't make verts */
|
|
|
|
TM_INDEX_SKIP = -1 /* dont make verts (when the index values point to trans-verts) */
|
|
|
|
};
|
|
|
|
|
|
|
|
/* copied from editobject.c, needs to be replaced with new transform code still */
|
|
|
|
/* mode flags: */
|
|
|
|
enum {
|
|
|
|
TM_ALL_JOINTS = 1, /* all joints (for bones only) */
|
|
|
|
TM_SKIP_HANDLES = 2 /* skip handles when control point is selected (for curves only) */
|
|
|
|
};
|
|
|
|
|
2012-04-09 07:06:06 +00:00
|
|
|
static void set_mapped_co(void *vuserdata, int index, const float co[3],
|
|
|
|
const float UNUSED(no[3]), const short UNUSED(no_s[3]))
|
2011-04-15 02:45:02 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
void **userdata = vuserdata;
|
2011-04-15 02:45:02 +00:00
|
|
|
BMEditMesh *em = userdata[0];
|
|
|
|
TransVert *tv = userdata[1];
|
2012-03-27 04:46:52 +00:00
|
|
|
BMVert *eve = EDBM_vert_at_index(em, index);
|
2011-04-15 02:45:02 +00:00
|
|
|
|
2012-11-05 10:43:52 +00:00
|
|
|
if (BM_elem_index_get(eve) != TM_INDEX_SKIP) {
|
|
|
|
tv = &tv[BM_elem_index_get(eve)];
|
|
|
|
|
|
|
|
/* be clever, get the closest vertex to the original,
|
|
|
|
* behaves most logically when the mirror modifier is used for eg [#33051]*/
|
|
|
|
if ((tv->flag & TX_VERT_USE_MAPLOC) == 0) {
|
|
|
|
/* first time */
|
|
|
|
copy_v3_v3(tv->maploc, co);
|
|
|
|
tv->flag |= TX_VERT_USE_MAPLOC;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* find best location to use */
|
|
|
|
if (len_squared_v3v3(eve->co, co) < len_squared_v3v3(eve->co, tv->maploc)) {
|
|
|
|
copy_v3_v3(tv->maploc, co);
|
|
|
|
}
|
|
|
|
}
|
2011-04-15 05:20:18 +00:00
|
|
|
}
|
2011-04-15 02:45:02 +00:00
|
|
|
}
|
|
|
|
|
2012-05-12 22:34:20 +00:00
|
|
|
static void make_trans_verts(Object *obedit, float min[3], float max[3], int mode)
|
2009-03-01 06:36:16 +00:00
|
|
|
{
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
2012-03-25 23:54:33 +00:00
|
|
|
TransVert *tv = NULL;
|
2009-03-01 06:36:16 +00:00
|
|
|
MetaElem *ml;
|
2009-05-16 16:18:08 +00:00
|
|
|
BMVert *eve;
|
2012-03-25 23:54:33 +00:00
|
|
|
EditBone *ebo;
|
2009-03-01 06:36:16 +00:00
|
|
|
float total, center[3], centroid[3];
|
|
|
|
int a;
|
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
tottrans = 0; /* global! */
|
|
|
|
|
2009-03-01 06:36:16 +00:00
|
|
|
INIT_MINMAX(min, max);
|
2012-03-23 20:18:09 +00:00
|
|
|
zero_v3(centroid);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (obedit->type == OB_MESH) {
|
2013-04-16 05:59:48 +00:00
|
|
|
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
2009-05-16 16:18:08 +00:00
|
|
|
BMesh *bm = em->bm;
|
2011-02-27 06:19:40 +00:00
|
|
|
BMIter iter;
|
2011-04-15 02:45:02 +00:00
|
|
|
void *userdata[2] = {em, NULL};
|
2012-10-26 04:14:10 +00:00
|
|
|
/*int proptrans = 0; */ /*UNUSED*/
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2011-11-16 12:38:40 +00:00
|
|
|
/* abuses vertex index all over, set, just set dirty here,
|
|
|
|
* perhaps this could use its own array instead? - campbell */
|
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
/* transform now requires awareness for select mode, so we tag the f1 flags in verts */
|
2012-03-25 23:54:33 +00:00
|
|
|
tottrans = 0;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (em->selectmode & SCE_SELECT_VERTEX) {
|
2012-04-19 13:47:58 +00:00
|
|
|
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
|
2012-11-05 10:33:59 +00:00
|
|
|
BM_elem_index_set(eve, TM_INDEX_ON); /* set_dirty! */
|
2009-03-01 06:36:16 +00:00
|
|
|
tottrans++;
|
|
|
|
}
|
2012-11-05 10:33:59 +00:00
|
|
|
else {
|
|
|
|
BM_elem_index_set(eve, TM_INDEX_OFF); /* set_dirty! */
|
|
|
|
}
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
else if (em->selectmode & SCE_SELECT_EDGE) {
|
2009-05-16 16:18:08 +00:00
|
|
|
BMEdge *eed;
|
|
|
|
|
2012-04-19 13:47:58 +00:00
|
|
|
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
|
2012-11-05 10:33:59 +00:00
|
|
|
BM_elem_index_set(eve, TM_INDEX_OFF); /* set_dirty! */
|
2012-03-25 23:54:33 +00:00
|
|
|
}
|
2009-05-16 16:18:08 +00:00
|
|
|
|
2012-04-19 13:47:58 +00:00
|
|
|
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BM_elem_flag_test(eed, BM_ELEM_SELECT)) {
|
2012-11-05 10:33:59 +00:00
|
|
|
BM_elem_index_set(eed->v1, TM_INDEX_ON); /* set_dirty! */
|
|
|
|
BM_elem_index_set(eed->v2, TM_INDEX_ON); /* set_dirty! */
|
2011-11-16 12:38:40 +00:00
|
|
|
}
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
2010-01-13 07:26:11 +00:00
|
|
|
|
2012-04-19 13:47:58 +00:00
|
|
|
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
|
2012-11-05 10:33:59 +00:00
|
|
|
if (BM_elem_index_get(eve) == TM_INDEX_ON) tottrans++;
|
2012-03-25 23:54:33 +00:00
|
|
|
}
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
else {
|
2009-05-16 16:18:08 +00:00
|
|
|
BMFace *efa;
|
|
|
|
|
2012-04-19 13:47:58 +00:00
|
|
|
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
|
2012-11-05 10:33:59 +00:00
|
|
|
BM_elem_index_set(eve, TM_INDEX_OFF); /* set_dirty! */
|
2012-03-25 23:54:33 +00:00
|
|
|
}
|
2009-05-16 16:18:08 +00:00
|
|
|
|
2012-04-19 13:47:58 +00:00
|
|
|
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
2009-05-16 16:18:08 +00:00
|
|
|
BMIter liter;
|
|
|
|
BMLoop *l;
|
|
|
|
|
2012-04-19 13:47:58 +00:00
|
|
|
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
2012-11-05 10:33:59 +00:00
|
|
|
BM_elem_index_set(l->v, TM_INDEX_ON); /* set_dirty! */
|
2009-05-16 16:18:08 +00:00
|
|
|
}
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
2009-05-16 16:18:08 +00:00
|
|
|
|
2012-04-19 13:47:58 +00:00
|
|
|
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
|
2012-11-05 10:33:59 +00:00
|
|
|
if (BM_elem_index_get(eve) == TM_INDEX_ON) tottrans++;
|
2012-04-19 11:44:12 +00:00
|
|
|
}
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
2012-03-01 12:20:18 +00:00
|
|
|
/* for any of the 3 loops above which all dirty the indices */
|
2011-11-16 12:38:40 +00:00
|
|
|
bm->elem_index_dirty |= BM_VERT;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* and now make transverts */
|
2012-02-22 16:52:06 +00:00
|
|
|
if (tottrans) {
|
2012-03-25 23:54:33 +00:00
|
|
|
tv = transvmain = MEM_callocN(tottrans * sizeof(TransVert), "maketransverts");
|
2011-04-15 02:45:02 +00:00
|
|
|
|
|
|
|
a = 0;
|
2012-04-19 13:47:58 +00:00
|
|
|
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (BM_elem_index_get(eve)) {
|
2012-11-05 10:33:59 +00:00
|
|
|
BM_elem_index_set(eve, a); /* set_dirty! */
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(tv->oldloc, eve->co);
|
2012-03-25 23:54:33 +00:00
|
|
|
tv->loc = eve->co;
|
2012-11-05 10:33:59 +00:00
|
|
|
tv->flag = (BM_elem_index_get(eve) == TM_INDEX_ON) ? SELECT : 0;
|
2009-03-01 06:36:16 +00:00
|
|
|
tv++;
|
2011-04-15 02:45:02 +00:00
|
|
|
a++;
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-11-05 10:33:59 +00:00
|
|
|
BM_elem_index_set(eve, TM_INDEX_SKIP); /* set_dirty! */
|
2012-02-22 16:52:06 +00:00
|
|
|
}
|
2011-04-15 02:45:02 +00:00
|
|
|
}
|
2011-11-16 12:38:40 +00:00
|
|
|
/* set dirty already, above */
|
|
|
|
|
2011-04-15 02:45:02 +00:00
|
|
|
userdata[1] = transvmain;
|
|
|
|
}
|
|
|
|
|
2011-04-15 07:13:45 +00:00
|
|
|
if (transvmain && em->derivedCage) {
|
2012-12-12 06:53:39 +00:00
|
|
|
EDBM_index_arrays_ensure(em, BM_VERT);
|
2011-04-15 07:13:45 +00:00
|
|
|
em->derivedCage->foreachMappedVert(em->derivedCage, set_mapped_co, userdata);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (obedit->type == OB_ARMATURE) {
|
|
|
|
bArmature *arm = obedit->data;
|
|
|
|
int totmalloc = BLI_countlist(arm->edbo);
|
2009-11-02 17:15:14 +00:00
|
|
|
|
2010-01-13 07:26:11 +00:00
|
|
|
totmalloc *= 2; /* probably overkill but bones can have 2 trans verts each */
|
2009-11-02 17:15:14 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
tv = transvmain = MEM_callocN(totmalloc * sizeof(TransVert), "maketransverts armature");
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (ebo = arm->edbo->first; ebo; ebo = ebo->next) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ebo->layer & arm->layer) {
|
2012-03-25 23:54:33 +00:00
|
|
|
short tipsel = (ebo->flag & BONE_TIPSEL);
|
|
|
|
short rootsel = (ebo->flag & BONE_ROOTSEL);
|
|
|
|
short rootok = (!(ebo->parent && (ebo->flag & BONE_CONNECTED) && (ebo->parent->flag & BONE_TIPSEL)));
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
if ((tipsel && rootsel) || (rootsel)) {
|
2010-09-25 06:45:28 +00:00
|
|
|
/* Don't add the tip (unless mode & TM_ALL_JOINTS, for getting all joints),
|
2009-03-01 06:36:16 +00:00
|
|
|
* otherwise we get zero-length bones as tips will snap to the same
|
2011-12-07 15:55:37 +00:00
|
|
|
* location as heads.
|
2009-03-01 06:36:16 +00:00
|
|
|
*/
|
|
|
|
if (rootok) {
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(tv->oldloc, ebo->head);
|
2012-03-25 23:54:33 +00:00
|
|
|
tv->loc = ebo->head;
|
2012-11-05 10:33:59 +00:00
|
|
|
tv->flag = SELECT;
|
2009-03-01 06:36:16 +00:00
|
|
|
tv++;
|
|
|
|
tottrans++;
|
2012-10-21 05:46:41 +00:00
|
|
|
}
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2010-09-25 06:45:28 +00:00
|
|
|
if ((mode & TM_ALL_JOINTS) && (tipsel)) {
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(tv->oldloc, ebo->tail);
|
2012-03-25 23:54:33 +00:00
|
|
|
tv->loc = ebo->tail;
|
2012-11-05 10:33:59 +00:00
|
|
|
tv->flag = SELECT;
|
2009-03-01 06:36:16 +00:00
|
|
|
tv++;
|
|
|
|
tottrans++;
|
2011-12-07 15:55:37 +00:00
|
|
|
}
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
else if (tipsel) {
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(tv->oldloc, ebo->tail);
|
2012-03-25 23:54:33 +00:00
|
|
|
tv->loc = ebo->tail;
|
2012-11-05 10:33:59 +00:00
|
|
|
tv->flag = SELECT;
|
2009-03-01 06:36:16 +00:00
|
|
|
tv++;
|
|
|
|
tottrans++;
|
|
|
|
}
|
2011-12-07 15:55:37 +00:00
|
|
|
}
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
Curve *cu = obedit->data;
|
|
|
|
int totmalloc = 0;
|
2012-04-28 16:49:00 +00:00
|
|
|
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
|
2010-07-25 11:57:36 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (nu = nurbs->first; nu; nu = nu->next) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (nu->type == CU_BEZIER)
|
2012-03-25 23:54:33 +00:00
|
|
|
totmalloc += 3 * nu->pntsu;
|
2009-03-01 06:36:16 +00:00
|
|
|
else
|
2012-03-25 23:54:33 +00:00
|
|
|
totmalloc += nu->pntsu * nu->pntsv;
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
tv = transvmain = MEM_callocN(totmalloc * sizeof(TransVert), "maketransverts curve");
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
nu = nurbs->first;
|
2012-02-22 16:52:06 +00:00
|
|
|
while (nu) {
|
|
|
|
if (nu->type == CU_BEZIER) {
|
2012-03-25 23:54:33 +00:00
|
|
|
a = nu->pntsu;
|
|
|
|
bezt = nu->bezt;
|
2012-02-22 16:52:06 +00:00
|
|
|
while (a--) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (bezt->hide == 0) {
|
|
|
|
int skip_handle = 0;
|
2012-02-22 16:52:06 +00:00
|
|
|
if (bezt->f2 & SELECT)
|
2012-03-25 23:54:33 +00:00
|
|
|
skip_handle = mode & TM_SKIP_HANDLES;
|
2010-09-25 06:45:28 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if ((bezt->f1 & SELECT) && !skip_handle) {
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(tv->oldloc, bezt->vec[0]);
|
2012-03-25 23:54:33 +00:00
|
|
|
tv->loc = bezt->vec[0];
|
|
|
|
tv->flag = bezt->f1 & SELECT;
|
2009-03-01 06:36:16 +00:00
|
|
|
tv++;
|
|
|
|
tottrans++;
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (bezt->f2 & SELECT) {
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(tv->oldloc, bezt->vec[1]);
|
2012-03-25 23:54:33 +00:00
|
|
|
tv->loc = bezt->vec[1];
|
|
|
|
tv->val = &(bezt->alfa);
|
|
|
|
tv->oldval = bezt->alfa;
|
|
|
|
tv->flag = bezt->f2 & SELECT;
|
2009-03-01 06:36:16 +00:00
|
|
|
tv++;
|
|
|
|
tottrans++;
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if ((bezt->f3 & SELECT) && !skip_handle) {
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(tv->oldloc, bezt->vec[2]);
|
2012-03-25 23:54:33 +00:00
|
|
|
tv->loc = bezt->vec[2];
|
|
|
|
tv->flag = bezt->f3 & SELECT;
|
2009-03-01 06:36:16 +00:00
|
|
|
tv++;
|
|
|
|
tottrans++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
a = nu->pntsu * nu->pntsv;
|
|
|
|
bp = nu->bp;
|
2012-02-22 16:52:06 +00:00
|
|
|
while (a--) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (bp->hide == 0) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (bp->f1 & SELECT) {
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(tv->oldloc, bp->vec);
|
2012-03-25 23:54:33 +00:00
|
|
|
tv->loc = bp->vec;
|
|
|
|
tv->val = &(bp->alfa);
|
|
|
|
tv->oldval = bp->alfa;
|
|
|
|
tv->flag = bp->f1 & SELECT;
|
2009-03-01 06:36:16 +00:00
|
|
|
tv++;
|
|
|
|
tottrans++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
nu = nu->next;
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (obedit->type == OB_MBALL) {
|
|
|
|
MetaBall *mb = obedit->data;
|
|
|
|
int totmalloc = BLI_countlist(mb->editelems);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
tv = transvmain = MEM_callocN(totmalloc * sizeof(TransVert), "maketransverts mball");
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
ml = mb->editelems->first;
|
2012-02-22 16:52:06 +00:00
|
|
|
while (ml) {
|
|
|
|
if (ml->flag & SELECT) {
|
2012-03-25 23:54:33 +00:00
|
|
|
tv->loc = &ml->x;
|
2010-07-31 10:58:10 +00:00
|
|
|
copy_v3_v3(tv->oldloc, tv->loc);
|
2012-03-25 23:54:33 +00:00
|
|
|
tv->val = &(ml->rad);
|
|
|
|
tv->oldval = ml->rad;
|
2012-11-05 10:33:59 +00:00
|
|
|
tv->flag = SELECT;
|
2009-03-01 06:36:16 +00:00
|
|
|
tv++;
|
|
|
|
tottrans++;
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
ml = ml->next;
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
else if (obedit->type == OB_LATTICE) {
|
|
|
|
Lattice *lt = obedit->data;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
bp = lt->editlatt->latt->def;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
tv = transvmain = MEM_callocN(a * sizeof(TransVert), "maketransverts latt");
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
while (a--) {
|
|
|
|
if (bp->f1 & SELECT) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (bp->hide == 0) {
|
2010-07-31 10:58:10 +00:00
|
|
|
copy_v3_v3(tv->oldloc, bp->vec);
|
2012-03-25 23:54:33 +00:00
|
|
|
tv->loc = bp->vec;
|
|
|
|
tv->flag = bp->f1 & SELECT;
|
2009-03-01 06:36:16 +00:00
|
|
|
tv++;
|
|
|
|
tottrans++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!tottrans && transvmain) {
|
2010-09-25 06:45:28 +00:00
|
|
|
/* prevent memory leak. happens for curves/latticies due to */
|
|
|
|
/* difficult condition of adding points to trans data */
|
|
|
|
MEM_freeN(transvmain);
|
2012-03-25 23:54:33 +00:00
|
|
|
transvmain = NULL;
|
2010-09-25 06:45:28 +00:00
|
|
|
}
|
|
|
|
|
2009-03-01 06:36:16 +00:00
|
|
|
/* cent etc */
|
2012-03-25 23:54:33 +00:00
|
|
|
tv = transvmain;
|
|
|
|
total = 0.0;
|
|
|
|
for (a = 0; a < tottrans; a++, tv++) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (tv->flag & SELECT) {
|
2010-07-31 10:58:10 +00:00
|
|
|
add_v3_v3(centroid, tv->oldloc);
|
2011-03-27 15:57:27 +00:00
|
|
|
total += 1.0f;
|
2012-05-13 11:05:52 +00:00
|
|
|
minmax_v3v3_v3(min, max, tv->oldloc);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (total != 0.0f) {
|
2012-03-25 23:54:33 +00:00
|
|
|
mul_v3_fl(centroid, 1.0f / total);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
|
2010-07-31 10:58:10 +00:00
|
|
|
mid_v3_v3v3(center, min, max);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* *********************** operators ******************** */
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int snap_sel_to_grid(bContext *C, wmOperator *UNUSED(op))
|
2009-03-01 06:36:16 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
Object *obedit = CTX_data_edit_object(C);
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
RegionView3D *rv3d = CTX_wm_region_data(C);
|
2009-03-01 06:36:16 +00:00
|
|
|
TransVert *tv;
|
|
|
|
float gridf, imat[3][3], bmat[3][3], vec[3];
|
|
|
|
int a;
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
gridf = rv3d->gridview;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (obedit) {
|
2012-03-25 23:54:33 +00:00
|
|
|
tottrans = 0;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 22:35:18 +00:00
|
|
|
if (ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL))
|
2009-03-01 06:36:16 +00:00
|
|
|
make_trans_verts(obedit, bmat[0], bmat[1], 0);
|
2012-03-25 23:54:33 +00:00
|
|
|
if (tottrans == 0) return OPERATOR_CANCELLED;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_m3_m4(bmat, obedit->obmat);
|
|
|
|
invert_m3_m3(imat, bmat);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
tv = transvmain;
|
|
|
|
for (a = 0; a < tottrans; a++, tv++) {
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(vec, tv->loc);
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_m3_v3(bmat, vec);
|
2010-04-21 12:27:48 +00:00
|
|
|
add_v3_v3(vec, obedit->obmat[3]);
|
2012-03-25 23:54:33 +00:00
|
|
|
vec[0] = gridf * floorf(0.5f + vec[0] / gridf);
|
|
|
|
vec[1] = gridf * floorf(0.5f + vec[1] / gridf);
|
|
|
|
vec[2] = gridf * floorf(0.5f + vec[2] / gridf);
|
2010-04-23 23:57:00 +00:00
|
|
|
sub_v3_v3(vec, obedit->obmat[3]);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_m3_v3(imat, vec);
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(tv->loc, vec);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
|
2010-10-15 12:29:02 +00:00
|
|
|
special_transvert_update(obedit);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
MEM_freeN(transvmain);
|
2012-03-25 23:54:33 +00:00
|
|
|
transvmain = NULL;
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-10-23 05:08:02 +00:00
|
|
|
struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-04-30 16:22:40 +00:00
|
|
|
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
|
|
|
|
{
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ob->mode & OB_MODE_POSE) {
|
2009-03-01 06:36:16 +00:00
|
|
|
bPoseChannel *pchan;
|
2012-03-25 23:54:33 +00:00
|
|
|
bArmature *arm = ob->data;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2011-12-07 15:55:37 +00:00
|
|
|
invert_m4_m4(ob->imat, ob->obmat);
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (pchan->bone->flag & BONE_SELECTED) {
|
|
|
|
if (pchan->bone->layer & arm->layer) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((pchan->bone->flag & BONE_CONNECTED) == 0) {
|
2011-12-07 15:55:37 +00:00
|
|
|
float nLoc[3];
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* get nearest grid point to snap to */
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(nLoc, pchan->pose_mat[3]);
|
2011-12-07 15:55:37 +00:00
|
|
|
/* We must operate in world space! */
|
|
|
|
mul_m4_v3(ob->obmat, nLoc);
|
2012-03-25 23:54:33 +00:00
|
|
|
vec[0] = gridf * (float)(floor(0.5f + nLoc[0] / gridf));
|
|
|
|
vec[1] = gridf * (float)(floor(0.5f + nLoc[1] / gridf));
|
|
|
|
vec[2] = gridf * (float)(floor(0.5f + nLoc[2] / gridf));
|
2011-12-07 15:55:37 +00:00
|
|
|
/* Back in object space... */
|
|
|
|
mul_m4_v3(ob->imat, vec);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-01-17 13:30:20 +00:00
|
|
|
/* Get location of grid point in pose space. */
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_armature_loc_pose_to_bone(pchan, vec, vec);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* adjust location */
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((pchan->protectflag & OB_LOCK_LOCX) == 0)
|
|
|
|
pchan->loc[0] = vec[0];
|
|
|
|
if ((pchan->protectflag & OB_LOCK_LOCY) == 0)
|
|
|
|
pchan->loc[1] = vec[1];
|
|
|
|
if ((pchan->protectflag & OB_LOCK_LOCZ) == 0)
|
|
|
|
pchan->loc[2] = vec[2];
|
2011-10-10 12:56:21 +00:00
|
|
|
|
|
|
|
/* auto-keyframing */
|
|
|
|
ED_autokeyframe_pchan(C, scene, ob, pchan, ks);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
2011-12-07 15:55:37 +00:00
|
|
|
/* if the bone has a parent and is connected to the parent,
|
|
|
|
* don't do anything - will break chain unless we do auto-ik.
|
2009-03-01 06:36:16 +00:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
ob->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2010-12-05 18:59:23 +00:00
|
|
|
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-09-30 06:12:47 +00:00
|
|
|
vec[0] = -ob->obmat[3][0] + gridf * floorf(0.5f + ob->obmat[3][0] / gridf);
|
|
|
|
vec[1] = -ob->obmat[3][1] + gridf * floorf(0.5f + ob->obmat[3][1] / gridf);
|
|
|
|
vec[2] = -ob->obmat[3][2] + gridf * floorf(0.5f + ob->obmat[3][2] / gridf);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ob->parent) {
|
2012-05-05 14:03:12 +00:00
|
|
|
BKE_object_where_is_calc(scene, ob);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
invert_m3_m3(imat, originmat);
|
|
|
|
mul_m3_v3(imat, vec);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((ob->protectflag & OB_LOCK_LOCX) == 0)
|
|
|
|
ob->loc[0] += vec[0];
|
|
|
|
if ((ob->protectflag & OB_LOCK_LOCY) == 0)
|
|
|
|
ob->loc[1] += vec[1];
|
|
|
|
if ((ob->protectflag & OB_LOCK_LOCZ) == 0)
|
|
|
|
ob->loc[2] += vec[2];
|
2010-12-21 18:55:49 +00:00
|
|
|
|
2009-03-01 06:36:16 +00:00
|
|
|
/* auto-keyframing */
|
2011-10-10 12:56:21 +00:00
|
|
|
ED_autokeyframe_object(C, scene, ob, ks);
|
2013-02-21 19:33:04 +00:00
|
|
|
|
|
|
|
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CTX_DATA_END;
|
|
|
|
}
|
2009-11-24 11:48:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Snap Selection to Grid";
|
|
|
|
ot->description = "Snap selected item(s) to nearest grid node";
|
|
|
|
ot->idname = "VIEW3D_OT_snap_selected_to_grid";
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = snap_sel_to_grid;
|
|
|
|
ot->poll = ED_operator_region_view3d_active;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* flags */
|
2012-03-25 23:54:33 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* *************************************************** */
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
|
2009-03-01 06:36:16 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
Object *obedit = CTX_data_edit_object(C);
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2009-03-01 06:36:16 +00:00
|
|
|
TransVert *tv;
|
|
|
|
float *curs, imat[3][3], bmat[3][3], vec[3];
|
|
|
|
int a;
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
curs = give_cursor(scene, v3d);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (obedit) {
|
2012-03-25 23:54:33 +00:00
|
|
|
tottrans = 0;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 22:35:18 +00:00
|
|
|
if (ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL))
|
2009-03-01 06:36:16 +00:00
|
|
|
make_trans_verts(obedit, bmat[0], bmat[1], 0);
|
2012-03-25 23:54:33 +00:00
|
|
|
if (tottrans == 0) return OPERATOR_CANCELLED;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_m3_m4(bmat, obedit->obmat);
|
|
|
|
invert_m3_m3(imat, bmat);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
tv = transvmain;
|
|
|
|
for (a = 0; a < tottrans; a++, tv++) {
|
2010-10-15 12:29:02 +00:00
|
|
|
sub_v3_v3v3(vec, curs, obedit->obmat[3]);
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_m3_v3(imat, vec);
|
2010-10-15 12:29:02 +00:00
|
|
|
copy_v3_v3(tv->loc, vec);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
|
2010-10-15 12:29:02 +00:00
|
|
|
special_transvert_update(obedit);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
MEM_freeN(transvmain);
|
2012-03-25 23:54:33 +00:00
|
|
|
transvmain = NULL;
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-10-23 05:08:02 +00:00
|
|
|
struct KeyingSet *ks = ANIM_get_keyingset_for_autokeying(scene, ANIM_KS_LOCATION_ID);
|
2011-10-10 12:56:21 +00:00
|
|
|
|
2012-04-30 16:22:40 +00:00
|
|
|
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
|
|
|
|
{
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ob->mode & OB_MODE_POSE) {
|
2009-03-01 06:36:16 +00:00
|
|
|
bPoseChannel *pchan;
|
2012-03-25 23:54:33 +00:00
|
|
|
bArmature *arm = ob->data;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
invert_m4_m4(ob->imat, ob->obmat);
|
2011-12-07 15:55:37 +00:00
|
|
|
copy_v3_v3(vec, curs);
|
|
|
|
mul_m4_v3(ob->imat, vec);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (pchan->bone->flag & BONE_SELECTED) {
|
|
|
|
if (pchan->bone->layer & arm->layer) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((pchan->bone->flag & BONE_CONNECTED) == 0) {
|
2012-01-17 13:30:20 +00:00
|
|
|
/* Get position in pchan (pose) space. */
|
2012-05-05 16:03:57 +00:00
|
|
|
BKE_armature_loc_pose_to_bone(pchan, vec, vec);
|
2012-01-17 13:30:20 +00:00
|
|
|
|
2010-12-21 18:55:49 +00:00
|
|
|
/* copy new position */
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((pchan->protectflag & OB_LOCK_LOCX) == 0)
|
|
|
|
pchan->loc[0] = vec[0];
|
|
|
|
if ((pchan->protectflag & OB_LOCK_LOCY) == 0)
|
|
|
|
pchan->loc[1] = vec[1];
|
|
|
|
if ((pchan->protectflag & OB_LOCK_LOCZ) == 0)
|
|
|
|
pchan->loc[2] = vec[2];
|
2011-10-10 12:56:21 +00:00
|
|
|
|
|
|
|
/* auto-keyframing */
|
|
|
|
ED_autokeyframe_pchan(C, scene, ob, pchan, ks);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
2011-12-07 15:55:37 +00:00
|
|
|
/* if the bone has a parent and is connected to the parent,
|
|
|
|
* don't do anything - will break chain unless we do auto-ik.
|
2009-03-01 06:36:16 +00:00
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
ob->pose->flag |= (POSE_LOCKED | POSE_DO_UNLOCK);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2010-12-05 18:59:23 +00:00
|
|
|
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
vec[0] = -ob->obmat[3][0] + curs[0];
|
|
|
|
vec[1] = -ob->obmat[3][1] + curs[1];
|
|
|
|
vec[2] = -ob->obmat[3][2] + curs[2];
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ob->parent) {
|
2012-05-05 14:03:12 +00:00
|
|
|
BKE_object_where_is_calc(scene, ob);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
invert_m3_m3(imat, originmat);
|
|
|
|
mul_m3_v3(imat, vec);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((ob->protectflag & OB_LOCK_LOCX) == 0)
|
|
|
|
ob->loc[0] += vec[0];
|
|
|
|
if ((ob->protectflag & OB_LOCK_LOCY) == 0)
|
|
|
|
ob->loc[1] += vec[1];
|
|
|
|
if ((ob->protectflag & OB_LOCK_LOCZ) == 0)
|
|
|
|
ob->loc[2] += vec[2];
|
2011-10-10 12:56:21 +00:00
|
|
|
|
2009-03-01 06:36:16 +00:00
|
|
|
/* auto-keyframing */
|
2011-10-10 12:56:21 +00:00
|
|
|
ED_autokeyframe_object(C, scene, ob, ks);
|
2013-02-21 19:33:04 +00:00
|
|
|
|
|
|
|
DAG_id_tag_update(&ob->id, OB_RECALC_OB);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
CTX_DATA_END;
|
|
|
|
}
|
2009-11-24 11:48:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Snap Selection to Cursor";
|
|
|
|
ot->description = "Snap selected item(s) to cursor";
|
|
|
|
ot->idname = "VIEW3D_OT_snap_selected_to_cursor";
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = snap_sel_to_curs;
|
|
|
|
ot->poll = ED_operator_view3d_active;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* flags */
|
2012-03-25 23:54:33 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* *************************************************** */
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int snap_curs_to_grid(bContext *C, wmOperator *UNUSED(op))
|
2009-03-01 06:36:16 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
RegionView3D *rv3d = CTX_wm_region_data(C);
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2009-03-01 06:36:16 +00:00
|
|
|
float gridf, *curs;
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
gridf = rv3d->gridview;
|
|
|
|
curs = give_cursor(scene, v3d);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
curs[0] = gridf * floorf(0.5f + curs[0] / gridf);
|
|
|
|
curs[1] = gridf * floorf(0.5f + curs[1] / gridf);
|
|
|
|
curs[2] = gridf * floorf(0.5f + curs[2] / gridf);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-07-08 20:36:00 +00:00
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); /* hrm */
|
|
|
|
|
2009-03-01 06:36:16 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VIEW3D_OT_snap_cursor_to_grid(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Snap Cursor to Grid";
|
|
|
|
ot->description = "Snap cursor to nearest grid node";
|
|
|
|
ot->idname = "VIEW3D_OT_snap_cursor_to_grid";
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = snap_curs_to_grid;
|
|
|
|
ot->poll = ED_operator_region_view3d_active;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* flags */
|
2012-03-25 23:54:33 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* **************************************************** */
|
|
|
|
|
2011-11-07 12:55:18 +00:00
|
|
|
static void bundle_midpoint(Scene *scene, Object *ob, float vec[3])
|
|
|
|
{
|
2012-05-05 14:03:12 +00:00
|
|
|
MovieClip *clip = BKE_object_movieclip_get(scene, ob, 0);
|
2011-12-31 03:45:31 +00:00
|
|
|
MovieTracking *tracking;
|
|
|
|
MovieTrackingObject *object;
|
2012-03-25 23:54:33 +00:00
|
|
|
int ok = 0;
|
2011-12-31 03:45:31 +00:00
|
|
|
float min[3], max[3], mat[4][4], pos[3], cammat[4][4] = MAT4_UNITY;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (!clip)
|
2011-11-07 12:55:18 +00:00
|
|
|
return;
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
tracking = &clip->tracking;
|
2011-12-15 16:10:49 +00:00
|
|
|
|
2012-01-04 11:20:50 +00:00
|
|
|
copy_m4_m4(cammat, ob->obmat);
|
2011-12-15 16:10:49 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
BKE_tracking_get_camera_object_matrix(scene, ob, mat);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
INIT_MINMAX(min, max);
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
for (object = tracking->objects.first; object; object = object->next) {
|
2012-06-15 11:03:23 +00:00
|
|
|
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
|
2012-03-25 23:54:33 +00:00
|
|
|
MovieTrackingTrack *track = tracksbase->first;
|
2011-12-15 16:10:49 +00:00
|
|
|
float obmat[4][4];
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (object->flag & TRACKING_OBJECT_CAMERA) {
|
2011-12-15 16:10:49 +00:00
|
|
|
copy_m4_m4(obmat, mat);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
float imat[4][4];
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, scene->r.cfra, imat);
|
2011-12-15 16:10:49 +00:00
|
|
|
invert_m4(imat);
|
|
|
|
|
2011-12-19 10:39:40 +00:00
|
|
|
mult_m4_m4m4(obmat, cammat, imat);
|
2011-12-15 16:10:49 +00:00
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
while (track) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if ((track->flag & TRACK_HAS_BUNDLE) && TRACK_SELECTED(track)) {
|
|
|
|
ok = 1;
|
2011-12-15 16:10:49 +00:00
|
|
|
mul_v3_m4v3(pos, obmat, track->bundle_pos);
|
2012-05-13 11:05:52 +00:00
|
|
|
minmax_v3v3_v3(min, max, pos);
|
2011-12-15 16:10:49 +00:00
|
|
|
}
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
track = track->next;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (ok) {
|
2011-11-08 09:02:47 +00:00
|
|
|
mid_v3_v3v3(vec, min, max);
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op))
|
2009-03-01 06:36:16 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
Object *obedit = CTX_data_edit_object(C);
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2009-03-01 06:36:16 +00:00
|
|
|
TransVert *tv;
|
|
|
|
float *curs, bmat[3][3], vec[3], min[3], max[3], centroid[3];
|
|
|
|
int count, a;
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
curs = give_cursor(scene, v3d);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
count = 0;
|
2009-03-01 06:36:16 +00:00
|
|
|
INIT_MINMAX(min, max);
|
2012-03-23 20:18:09 +00:00
|
|
|
zero_v3(centroid);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (obedit) {
|
2012-03-25 23:54:33 +00:00
|
|
|
tottrans = 0;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 22:35:18 +00:00
|
|
|
if (ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL))
|
2012-03-25 23:54:33 +00:00
|
|
|
make_trans_verts(obedit, bmat[0], bmat[1], TM_ALL_JOINTS | TM_SKIP_HANDLES);
|
|
|
|
if (tottrans == 0) return OPERATOR_CANCELLED;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_m3_m4(bmat, obedit->obmat);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
tv = transvmain;
|
|
|
|
for (a = 0; a < tottrans; a++, tv++) {
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(vec, tv->loc);
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_m3_v3(bmat, vec);
|
2010-04-21 12:27:48 +00:00
|
|
|
add_v3_v3(vec, obedit->obmat[3]);
|
|
|
|
add_v3_v3(centroid, vec);
|
2012-05-13 11:05:52 +00:00
|
|
|
minmax_v3v3_v3(min, max, vec);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
if (v3d->around == V3D_CENTROID) {
|
|
|
|
mul_v3_fl(centroid, 1.0f / (float)tottrans);
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(curs, centroid);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-04-19 05:34:05 +00:00
|
|
|
mid_v3_v3v3(curs, min, max);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
MEM_freeN(transvmain);
|
2012-03-25 23:54:33 +00:00
|
|
|
transvmain = NULL;
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
else {
|
2012-03-25 23:54:33 +00:00
|
|
|
Object *obact = CTX_data_active_object(C);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-02-22 16:52:06 +00:00
|
|
|
if (obact && (obact->mode & OB_MODE_POSE)) {
|
2012-03-25 23:54:33 +00:00
|
|
|
bArmature *arm = obact->data;
|
2009-03-01 06:36:16 +00:00
|
|
|
bPoseChannel *pchan;
|
2012-03-25 23:54:33 +00:00
|
|
|
for (pchan = obact->pose->chanbase.first; pchan; pchan = pchan->next) {
|
2012-02-22 16:52:06 +00:00
|
|
|
if (arm->layer & pchan->bone->layer) {
|
|
|
|
if (pchan->bone->flag & BONE_SELECTED) {
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(vec, pchan->pose_head);
|
2010-12-03 12:30:59 +00:00
|
|
|
mul_m4_v3(obact->obmat, vec);
|
2010-04-21 12:27:48 +00:00
|
|
|
add_v3_v3(centroid, vec);
|
2012-05-13 11:05:52 +00:00
|
|
|
minmax_v3v3_v3(min, max, vec);
|
2009-03-01 06:36:16 +00:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2012-04-30 16:22:40 +00:00
|
|
|
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
|
|
|
|
{
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(vec, ob->obmat[3]);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
/* special case for camera -- snap to bundles */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (ob->type == OB_CAMERA) {
|
2011-11-07 12:55:18 +00:00
|
|
|
/* snap to bundles should happen only when bundles are visible */
|
2012-03-25 23:54:33 +00:00
|
|
|
if (v3d->flag2 & V3D_SHOW_RECONSTRUCTION) {
|
2011-11-07 12:55:18 +00:00
|
|
|
bundle_midpoint(scene, ob, vec);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-04-21 12:27:48 +00:00
|
|
|
add_v3_v3(centroid, vec);
|
2012-05-13 11:05:52 +00:00
|
|
|
minmax_v3v3_v3(min, max, vec);
|
2009-03-01 06:36:16 +00:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
CTX_DATA_END;
|
|
|
|
}
|
2012-02-22 16:52:06 +00:00
|
|
|
if (count) {
|
2012-03-25 23:54:33 +00:00
|
|
|
if (v3d->around == V3D_CENTROID) {
|
|
|
|
mul_v3_fl(centroid, 1.0f / (float)count);
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(curs, centroid);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
else {
|
2011-04-19 05:34:05 +00:00
|
|
|
mid_v3_v3v3(curs, min, max);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-03-25 23:54:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Snap Cursor to Selected";
|
|
|
|
ot->description = "Snap cursor to center of selected item(s)";
|
|
|
|
ot->idname = "VIEW3D_OT_snap_cursor_to_selected";
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = snap_curs_to_sel;
|
|
|
|
ot->poll = ED_operator_view3d_active;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* flags */
|
2012-03-25 23:54:33 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ********************************************** */
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int snap_curs_to_active(bContext *C, wmOperator *UNUSED(op))
|
2009-03-01 06:36:16 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
Object *obedit = CTX_data_edit_object(C);
|
|
|
|
Object *obact = CTX_data_active_object(C);
|
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2009-03-01 06:36:16 +00:00
|
|
|
float *curs;
|
|
|
|
|
|
|
|
curs = give_cursor(scene, v3d);
|
|
|
|
|
2012-02-27 10:35:39 +00:00
|
|
|
if (obedit) {
|
2009-03-01 06:36:16 +00:00
|
|
|
if (obedit->type == OB_MESH) {
|
2013-04-16 05:59:48 +00:00
|
|
|
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
2009-03-01 06:36:16 +00:00
|
|
|
/* check active */
|
2009-05-16 16:18:08 +00:00
|
|
|
BMEditSelection ese;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-09-10 03:34:43 +00:00
|
|
|
if (BM_select_history_active_get(em->bm, &ese)) {
|
2012-04-24 21:19:18 +00:00
|
|
|
BM_editselection_center(&ese, curs);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_m4_v3(obedit->obmat, curs);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
2009-10-29 09:14:20 +00:00
|
|
|
if (obact) {
|
2011-10-28 12:40:15 +00:00
|
|
|
copy_v3_v3(curs, obact->obmat[3]);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
|
2009-03-01 06:36:16 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Snap Cursor to Active";
|
|
|
|
ot->description = "Snap cursor to active item";
|
|
|
|
ot->idname = "VIEW3D_OT_snap_cursor_to_active";
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = snap_curs_to_active;
|
|
|
|
ot->poll = ED_operator_view3d_active;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
/* flags */
|
2012-03-25 23:54:33 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
|
2010-01-13 22:17:56 +00:00
|
|
|
/* **************************************************** */
|
|
|
|
/*New Code - Snap Cursor to Center -*/
|
2010-10-15 01:36:14 +00:00
|
|
|
static int snap_curs_to_center(bContext *C, wmOperator *UNUSED(op))
|
2009-03-01 06:36:16 +00:00
|
|
|
{
|
2012-03-25 23:54:33 +00:00
|
|
|
Scene *scene = CTX_data_scene(C);
|
|
|
|
View3D *v3d = CTX_wm_view3d(C);
|
2010-03-22 09:30:00 +00:00
|
|
|
float *curs;
|
2012-03-25 23:54:33 +00:00
|
|
|
curs = give_cursor(scene, v3d);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
zero_v3(curs);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2010-01-13 22:17:56 +00:00
|
|
|
void VIEW3D_OT_snap_cursor_to_center(wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->name = "Snap Cursor to Center";
|
|
|
|
ot->description = "Snap cursor to the Center";
|
|
|
|
ot->idname = "VIEW3D_OT_snap_cursor_to_center";
|
2010-01-13 22:17:56 +00:00
|
|
|
|
2011-12-07 15:55:37 +00:00
|
|
|
/* api callbacks */
|
2012-03-22 07:26:09 +00:00
|
|
|
ot->exec = snap_curs_to_center;
|
|
|
|
ot->poll = ED_operator_view3d_active;
|
2010-01-13 22:17:56 +00:00
|
|
|
|
2010-03-22 09:30:00 +00:00
|
|
|
/* flags */
|
2012-03-25 23:54:33 +00:00
|
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
2010-01-13 22:17:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* **************************************************** */
|
|
|
|
|
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
bool ED_view3d_minmax_verts(Object *obedit, float min[3], float max[3])
|
2009-03-01 06:36:16 +00:00
|
|
|
{
|
|
|
|
TransVert *tv;
|
|
|
|
float centroid[3], vec[3], bmat[3][3];
|
|
|
|
int a;
|
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
tottrans = 0;
|
2012-03-25 22:35:18 +00:00
|
|
|
if (ELEM5(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE))
|
2010-09-25 06:45:28 +00:00
|
|
|
make_trans_verts(obedit, bmat[0], bmat[1], TM_ALL_JOINTS);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
if (tottrans == 0) return false;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_m3_m4(bmat, obedit->obmat);
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2012-03-25 23:54:33 +00:00
|
|
|
tv = transvmain;
|
|
|
|
for (a = 0; a < tottrans; a++, tv++) {
|
2012-02-03 02:36:03 +00:00
|
|
|
copy_v3_v3(vec, (tv->flag & TX_VERT_USE_MAPLOC) ? tv->maploc : tv->loc);
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_m3_v3(bmat, vec);
|
2010-04-21 12:27:48 +00:00
|
|
|
add_v3_v3(vec, obedit->obmat[3]);
|
|
|
|
add_v3_v3(centroid, vec);
|
2012-05-13 11:05:52 +00:00
|
|
|
minmax_v3v3_v3(min, max, vec);
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(transvmain);
|
2012-03-25 23:54:33 +00:00
|
|
|
transvmain = NULL;
|
2009-03-01 06:36:16 +00:00
|
|
|
|
2013-03-20 23:14:18 +00:00
|
|
|
return true;
|
2009-03-01 06:36:16 +00:00
|
|
|
}
|