Done BMESH_TODO in object/object_vgroup.c (make getSurroundingVerts() use polys/loops instead of tessfaces).
Also done a few optimizations of related code (OBJECT_OT_vertex_group_fix operator).
This commit is contained in:
@@ -48,6 +48,7 @@
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_particle_types.h"
|
||||
|
||||
#include "BLI_array.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_utildefines.h"
|
||||
@@ -748,100 +749,68 @@ static void vgroup_normalize(Object *ob)
|
||||
}
|
||||
}
|
||||
|
||||
/* This adds the indices of vertices to a list if they are not already present
|
||||
It returns the number that it added (0-2)
|
||||
It relies on verts having -1 for unassigned indices
|
||||
*/
|
||||
static int tryToAddVerts(int *verts, int length, int a, int b)
|
||||
{
|
||||
char containsA = FALSE;
|
||||
char containsB = FALSE;
|
||||
int added = 0;
|
||||
int i;
|
||||
for(i = 0; i < length && (!containsA || !containsB); i++) {
|
||||
if(verts[i] == a) {
|
||||
containsA = TRUE;
|
||||
} else if(verts[i] == b) {
|
||||
containsB = TRUE;
|
||||
} else if(verts[i] == -1) {
|
||||
if(!containsA) {
|
||||
verts[i] = a;
|
||||
containsA = TRUE;
|
||||
added++;
|
||||
} else if(!containsB){
|
||||
verts[i] = b;
|
||||
containsB = TRUE;
|
||||
added++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return added;
|
||||
}
|
||||
|
||||
/* BMESH_TODO - use MPoly's */
|
||||
|
||||
/* This finds all of the vertices connected to vert by an edge
|
||||
and returns an array of indices of size count
|
||||
|
||||
count is an int passed by reference so it can be assigned the value of the length here.
|
||||
*/
|
||||
/* This finds all of the vertices face-connected to vert by an edge and returns a
|
||||
* MEM_allocated array of indices of size count.
|
||||
* count is an int passed by reference so it can be assigned the value of the length here. */
|
||||
static int* getSurroundingVerts(Mesh *me, int vert, int *count)
|
||||
{
|
||||
int length = 0;
|
||||
int *tverts;
|
||||
MPoly *mp = me->mpoly;
|
||||
int i = me->totpoly;
|
||||
/* Instead of looping twice on all polys and loops, and use a temp array, let's rather
|
||||
* use a BLI_array, with a reasonable starting/reserved size (typically, there are not
|
||||
* many vertices face-linked to another one, even 8 might be too high...). */
|
||||
int *verts = NULL;
|
||||
MFace *mf = me->mface;
|
||||
int totface = me->totface;
|
||||
int found = 0;
|
||||
int i;
|
||||
for(i = 0; i < totface; i++, mf++) {
|
||||
if(vert == mf->v1 || vert == mf->v2 || vert == mf->v3 || (mf->v4 &&vert == mf->v4)) {
|
||||
length+=2;
|
||||
}
|
||||
}
|
||||
if(!length) {
|
||||
return NULL;
|
||||
}
|
||||
tverts = MEM_mallocN(sizeof(int)*length, "tempSurroundingVerts");
|
||||
mf = me->mface;
|
||||
for(i = 0; i < length; i++) {
|
||||
tverts[i] = -1;
|
||||
}
|
||||
for(i = 0; i < totface; i++, mf++) {
|
||||
int a=-1, b=-1;
|
||||
if(mf->v1 == vert) {
|
||||
a = mf->v2;
|
||||
if(mf->v4) {
|
||||
b = mf->v4;
|
||||
} else {
|
||||
b = mf->v3;
|
||||
BLI_array_declare(verts);
|
||||
|
||||
BLI_array_reserve(verts, 8);
|
||||
while(i--) {
|
||||
int j = mp->totloop;
|
||||
int first_l = mp->totloop - 1;
|
||||
MLoop *ml = &me->mloop[mp->loopstart];
|
||||
while(j--) {
|
||||
/* XXX This assume a vert can only be once in a poly, even though
|
||||
* it seems logical to me, not totaly sure of that. */
|
||||
if (ml->v == vert) {
|
||||
int a, b, k;
|
||||
if(j == first_l) {
|
||||
/* We are on the first corner. */
|
||||
a = ml[1].v;
|
||||
b = ml[j].v;
|
||||
}
|
||||
else if(!j) {
|
||||
/* We are on the last corner. */
|
||||
a = (ml-1)->v;
|
||||
b = me->mloop[mp->loopstart].v;
|
||||
}
|
||||
else {
|
||||
a = (ml-1)->v;
|
||||
b = (ml+1)->v;
|
||||
}
|
||||
|
||||
/* Append a and b verts to array, if not yet present. */
|
||||
k = BLI_array_count(verts);
|
||||
/* XXX Maybe a == b is enough? */
|
||||
while(k-- && !(a == b && a == -1)) {
|
||||
if(verts[k] == a)
|
||||
a = -1;
|
||||
else if(verts[k] == b)
|
||||
b = -1;
|
||||
}
|
||||
if(a != -1)
|
||||
BLI_array_append(verts, a);
|
||||
if(b != -1)
|
||||
BLI_array_append(verts, b);
|
||||
|
||||
/* Vert found in this poly, we can go to next one! */
|
||||
break;
|
||||
}
|
||||
} else if(mf->v2 == vert) {
|
||||
a = mf->v1;
|
||||
b = mf->v3;
|
||||
} else if(mf->v3 == vert) {
|
||||
a = mf->v2;
|
||||
if(mf->v4) {
|
||||
b = mf->v4;
|
||||
} else {
|
||||
b = mf->v1;
|
||||
}
|
||||
} else if (mf->v4 && mf->v4 == vert){
|
||||
a = mf->v1;
|
||||
b = mf->v3;
|
||||
} else {
|
||||
continue;
|
||||
ml++;
|
||||
}
|
||||
found += tryToAddVerts(tverts, length, a, b);
|
||||
mp++;
|
||||
}
|
||||
if(found) {
|
||||
verts = MEM_mallocN(sizeof(int)* found, "surroundingVerts");
|
||||
for(i = 0; i < found; i++) {
|
||||
verts[i] = tverts[i];
|
||||
}
|
||||
*count = found;
|
||||
}
|
||||
MEM_freeN(tverts);
|
||||
|
||||
/* Do not free the array! */
|
||||
*count = BLI_array_count(verts);
|
||||
return verts;
|
||||
}
|
||||
|
||||
@@ -1087,12 +1056,11 @@ static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength,
|
||||
|
||||
Mesh *me = ob->data;
|
||||
MVert *mvert = me->mvert;
|
||||
const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0;
|
||||
int *verts = NULL;
|
||||
if(!(me->editflag & ME_EDIT_VERT_SEL))
|
||||
return;
|
||||
for(i = 0; i < me->totvert && mvert; i++, mvert++) {
|
||||
|
||||
if(use_vert_sel && (mvert->flag & SELECT)) {
|
||||
|
||||
if(mvert->flag & SELECT) {
|
||||
int count=0;
|
||||
if((verts = getSurroundingVerts(me, i, &count))) {
|
||||
MVert m;
|
||||
@@ -1100,7 +1068,8 @@ static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength,
|
||||
int k;
|
||||
|
||||
DerivedMesh *dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
|
||||
for(k = 0; k < count; k++) {
|
||||
k = count;
|
||||
while(k--) {
|
||||
dm->getVert(dm, verts[k], &m);
|
||||
p[k] = m;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user