avoid using BLI_array for remove double helper function - bmesh_find_doubles_common(), was growing and array one at a time (with re-allocs), when the size is known.

This commit is contained in:
Campbell Barton 2012-11-05 14:39:49 +00:00
parent 5a8d5f77af
commit 964f29797b
3 changed files with 44 additions and 29 deletions

@ -285,6 +285,8 @@ void BMO_slot_int_set(BMOperator *op, const char *slot_name, const int i);
int BMO_slot_int_get(BMOperator *op, const char *slot_name); int BMO_slot_int_get(BMOperator *op, const char *slot_name);
void BMO_slot_bool_set(BMOperator *op, const char *slot_name, const int i); void BMO_slot_bool_set(BMOperator *op, const char *slot_name, const int i);
int BMO_slot_bool_get(BMOperator *op, const char *slot_name); int BMO_slot_bool_get(BMOperator *op, const char *slot_name);
void *BMO_slot_as_arrayN(BMOperator *op, const char *slot_name, int *len);
/* don't pass in arrays that are supposed to map to elements this way. /* don't pass in arrays that are supposed to map to elements this way.
* *

@ -429,6 +429,20 @@ int BMO_slot_bool_get(BMOperator *op, const char *slot_name)
return slot->data.i; return slot->data.i;
} }
/* if you want a copy of the elem buffer */
void *BMO_slot_as_arrayN(BMOperator *op, const char *slot_name, int *len)
{
BMOpSlot *slot = BMO_slot_get(op, slot_name);
void *ret;
/* could add support for mapping type */
BLI_assert(slot->slot_type == BMO_OP_SLOT_ELEMENT_BUF);
ret = MEM_mallocN(sizeof(void *) * slot->len, __func__);
memcpy(ret, slot->data.buf, sizeof(void *) * slot->len);
*len = slot->len;
return ret;
}
void *BMO_slot_ptr_get(BMOperator *op, const char *slot_name) void *BMO_slot_ptr_get(BMOperator *op, const char *slot_name)
{ {

@ -488,72 +488,71 @@ void bmo_collapse_uvs_exec(BMesh *bm, BMOperator *op)
static void bmesh_find_doubles_common(BMesh *bm, BMOperator *op, BMOperator *optarget, const char *targetmapname) static void bmesh_find_doubles_common(BMesh *bm, BMOperator *op, BMOperator *optarget, const char *targetmapname)
{ {
BMOIter oiter; BMVert **verts;
BMVert *v, *v2; int verts_len;
BMVert **verts = NULL;
BLI_array_declare(verts);
float dist, dist3;
int i, j, len, keepvert = 0;
dist = BMO_slot_float_get(op, "dist"); int i, j, keepvert = 0;
dist3 = dist * 3.0f;
i = 0; const float dist = BMO_slot_float_get(op, "dist");
BMO_ITER (v, &oiter, bm, op, "verts", BM_VERT) { const float dist3 = dist * 3.0f;
BLI_array_grow_one(verts);
verts[i++] = v;
}
/* Test whether keep_verts arg exists and is non-empty */ /* Test whether keep_verts arg exists and is non-empty */
if (BMO_slot_exists(op, "keep_verts")) { if (BMO_slot_exists(op, "keep_verts")) {
BMOIter oiter;
keepvert = BMO_iter_new(&oiter, bm, op, "keep_verts", BM_VERT) != NULL; keepvert = BMO_iter_new(&oiter, bm, op, "keep_verts", BM_VERT) != NULL;
} }
/* get the verts as an array we can sort */
verts = BMO_slot_as_arrayN(op, "verts", &verts_len);
/* sort by vertex coordinates added together */ /* sort by vertex coordinates added together */
qsort(verts, BLI_array_count(verts), sizeof(void *), vergaverco); qsort(verts, verts_len, sizeof(BMVert *), vergaverco);
/* Flag keep_verts */ /* Flag keep_verts */
if (keepvert) { if (keepvert) {
BMO_slot_buffer_flag_enable(bm, op, "keep_verts", BM_VERT, VERT_KEEP); BMO_slot_buffer_flag_enable(bm, op, "keep_verts", BM_VERT, VERT_KEEP);
} }
len = BLI_array_count(verts); for (i = 0; i < verts_len; i++) {
for (i = 0; i < len; i++) { BMVert *v_check = verts[i];
v = verts[i];
if (BMO_elem_flag_test(bm, v, VERT_DOUBLE)) { if (BMO_elem_flag_test(bm, v_check, VERT_DOUBLE)) {
continue; continue;
} }
for (j = i + 1; j < len; j++) { for (j = i + 1; j < verts_len; j++) {
v2 = verts[j]; BMVert *v_other = verts[j];
/* Compare sort values of the verts using 3x tolerance (allowing for the tolerance /* Compare sort values of the verts using 3x tolerance (allowing for the tolerance
* on each of the three axes). This avoids the more expensive length comparison * on each of the three axes). This avoids the more expensive length comparison
* for most vertex pairs. */ * for most vertex pairs. */
if ((v2->co[0] + v2->co[1] + v2->co[2]) - (v->co[0] + v->co[1] + v->co[2]) > dist3) if ((v_other->co[0] + v_other->co[1] + v_other->co[2]) -
(v_check->co[0] + v_check->co[1] + v_check->co[2]) > dist3)
{
break; break;
}
if (keepvert) { if (keepvert) {
if (BMO_elem_flag_test(bm, v2, VERT_KEEP) == BMO_elem_flag_test(bm, v, VERT_KEEP)) if (BMO_elem_flag_test(bm, v_other, VERT_KEEP) == BMO_elem_flag_test(bm, v_check, VERT_KEEP))
continue; continue;
} }
if (compare_len_v3v3(v->co, v2->co, dist)) { if (compare_len_v3v3(v_check->co, v_other->co, dist)) {
/* If one vert is marked as keep, make sure it will be the target */ /* If one vert is marked as keep, make sure it will be the target */
if (BMO_elem_flag_test(bm, v2, VERT_KEEP)) { if (BMO_elem_flag_test(bm, v_other, VERT_KEEP)) {
SWAP(BMVert *, v, v2); SWAP(BMVert *, v_check, v_other);
} }
BMO_elem_flag_enable(bm, v2, VERT_DOUBLE); BMO_elem_flag_enable(bm, v_other, VERT_DOUBLE);
BMO_elem_flag_enable(bm, v, VERT_TARGET); BMO_elem_flag_enable(bm, v_check, VERT_TARGET);
BMO_slot_map_ptr_insert(bm, optarget, targetmapname, v2, v); BMO_slot_map_ptr_insert(bm, optarget, targetmapname, v_other, v_check);
} }
} }
} }
BLI_array_free(verts); MEM_freeN(verts);
} }
void bmo_remove_doubles_exec(BMesh *bm, BMOperator *op) void bmo_remove_doubles_exec(BMesh *bm, BMOperator *op)