diff options
author | Martin Poirier <theeth@yahoo.com> | 2007-03-24 23:57:15 +0300 |
---|---|---|
committer | Martin Poirier <theeth@yahoo.com> | 2007-03-24 23:57:15 +0300 |
commit | 600c62a32d318e13f104f35cb4b2e44ea550a33d (patch) | |
tree | 2badee290118972ea4f2b6b9dabdd95a7d06e5ac /source/blender/src/transform_snap.c | |
parent | d6411c206d7f5ad7e01fc15831e0431fc6dabd11 (diff) |
=== Transform Snap ===
Inter-mesh snap optimization and fixes.
For larger meshes, tests are made against the bounding box first to speed things up (suggested by Brecht).
Also, verts are accessed through mesh_get_mapped_verts_nors() it can snapped to deformed vertices (only the deformed originals, not new verts for now).
Diffstat (limited to 'source/blender/src/transform_snap.c')
-rw-r--r-- | source/blender/src/transform_snap.c | 101 |
1 files changed, 82 insertions, 19 deletions
diff --git a/source/blender/src/transform_snap.c b/source/blender/src/transform_snap.c index c4ebe4ae0a0..8fc192f1e75 100644 --- a/source/blender/src/transform_snap.c +++ b/source/blender/src/transform_snap.c @@ -40,6 +40,7 @@ #include "DNA_scene_types.h" #include "DNA_meshdata_types.h" // Temporary, for snapping to other unselected meshes #include "DNA_space_types.h" +#include "DNA_screen_types.h" #include "DNA_userdef_types.h" #include "DNA_view3d_types.h" @@ -58,9 +59,13 @@ #include "BKE_global.h" #include "BKE_utildefines.h" +#include "BKE_DerivedMesh.h" +#include "BKE_object.h" #include "BSE_view.h" +#include "MEM_guardedalloc.h" + #include "transform.h" #include "mydevice.h" /* for KEY defines */ #include "blendef.h" /* for selection modes */ @@ -481,7 +486,7 @@ int findNearestVertFromObjects(int *dist, float *loc) { short mval[2]; getmouseco_areawin(mval); - + base= FIRSTBASE; for ( base = FIRSTBASE; base != NULL; base = base->next ) { if ( TESTBASE(base) && base != BASACT ) { @@ -489,27 +494,85 @@ int findNearestVertFromObjects(int *dist, float *loc) { if (ob->type == OB_MESH) { Mesh *me = ob->data; - int i; - for( i = 0; i < me->totvert; i++) { - MVert vert = me->mvert[i]; - float gloc[3]; - int sloc[2]; - int curdist; - - VECCOPY(gloc, vert.co); - Mat4MulVecfl(ob->obmat, gloc); - project_int(gloc, sloc); + if (me->totvert > 0) { + int test = 1; + int i; - sloc[0] -= mval[0]; - sloc[1] -= mval[1]; - - curdist = abs(sloc[0]) + abs(sloc[1]); + /* If number of vert is more than an arbitrary limit, + * test against boundbox first + * */ + if (me->totvert > 16) { + struct BoundBox *bb = object_get_boundbox(ob); + + int minx = 0, miny = 0, maxx = 0, maxy = 0; + int i; + + for (i = 0; i < 8; i++) { + float gloc[3]; + int sloc[2]; + + VECCOPY(gloc, bb->vec[i]); + Mat4MulVecfl(ob->obmat, gloc); + project_int(gloc, sloc); + + if (i == 0) { + minx = maxx = sloc[0]; + miny = maxy = sloc[1]; + } + else { + if (minx > sloc[0]) minx = sloc[0]; + else if (maxx < sloc[0]) maxx = sloc[0]; + + if (miny > sloc[1]) miny = sloc[1]; + else if (maxy < sloc[1]) maxy = sloc[1]; + } + } + + /* Pad with distance */ + + minx -= *dist; + miny -= *dist; + maxx += *dist; + maxy += *dist; + + if (mval[0] > maxx || mval[0] < minx || + mval[1] > maxy || mval[1] < miny) { + + test = 0; + } + } - if (curdist < *dist) { - *dist = curdist; - retval = 1; - VECCOPY(loc, gloc); + if (test == 1) { + float *verts = mesh_get_mapped_verts_nors(ob); + + if (verts != NULL) { + float *fp; + + fp = verts; + for( i = 0; i < me->totvert; i++, fp += 6) { + float gloc[3]; + int sloc[2]; + int curdist; + + VECCOPY(gloc, fp); + Mat4MulVecfl(ob->obmat, gloc); + project_int(gloc, sloc); + + sloc[0] -= mval[0]; + sloc[1] -= mval[1]; + + curdist = abs(sloc[0]) + abs(sloc[1]); + + if (curdist < *dist) { + *dist = curdist; + retval = 1; + VECCOPY(loc, gloc); + } + } + } + + MEM_freeN(verts); } } } |