[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56618] trunk/blender/source/blender: bmesh: optimize bmesh_vert_separate, redice allocs ( best cast it wont do any allocs).
Campbell Barton
ideasman42 at gmail.com
Thu May 9 14:46:36 CEST 2013
Revision: 56618
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56618
Author: campbellbarton
Date: 2013-05-09 12:46:35 +0000 (Thu, 09 May 2013)
Log Message:
-----------
bmesh: optimize bmesh_vert_separate, redice allocs (best cast it wont do any allocs).
gives approx 16% overall speedup to edgesplit modifier.
also reduce size of smallhash stack, was 521, which got doubled and was quite large on the stack. reduce to 64.
Modified Paths:
--------------
trunk/blender/source/blender/blenlib/BLI_smallhash.h
trunk/blender/source/blender/bmesh/intern/bmesh_core.c
Modified: trunk/blender/source/blender/blenlib/BLI_smallhash.h
===================================================================
--- trunk/blender/source/blender/blenlib/BLI_smallhash.h 2013-05-09 11:43:48 UTC (rev 56617)
+++ trunk/blender/source/blender/blenlib/BLI_smallhash.h 2013-05-09 12:46:35 UTC (rev 56618)
@@ -43,7 +43,7 @@
} SmallHashEntry;
/*how much stack space to use before dynamically allocating memory*/
-#define SMSTACKSIZE 521
+#define SMSTACKSIZE 64
typedef struct SmallHash {
SmallHashEntry *table;
SmallHashEntry _stacktable[SMSTACKSIZE];
Modified: trunk/blender/source/blender/bmesh/intern/bmesh_core.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_core.c 2013-05-09 11:43:48 UTC (rev 56617)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_core.c 2013-05-09 12:46:35 UTC (rev 56618)
@@ -30,6 +30,7 @@
#include "BLI_math_vector.h"
#include "BLI_listbase.h"
#include "BLI_array.h"
+#include "BLI_smallhash.h"
#include "BLF_translation.h"
@@ -1890,45 +1891,62 @@
*/
bool bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len)
{
- BMEdge **stack = NULL;
- BLI_array_staticdeclare(stack, BM_DEFAULT_ITER_STACK_SIZE);
+ const int v_edgetot = BM_vert_face_count(v);
+ BMEdge **stack = BLI_array_alloca(stack, v_edgetot);
+ unsigned int _stack_i;
+
+ /* */
+#define STACK_INIT(stack) ((void)stack, (void)(_stack_i = 0))
+#define STACK_PUSH(stack, val) (void)((stack)[_stack_i++] = val)
+#define STACK_POP(stack) ((void)0, (_stack_i ? ((stack)[--_stack_i]) : NULL))
+#define STACK_FREE(stack) ((void)stack)
+
+ SmallHash visithash;
BMVert **verts = NULL;
- GHash *visithash;
BMIter eiter, liter;
BMLoop *l;
BMEdge *e;
int i, maxindex;
BMLoop *l_new;
- visithash = BLI_ghash_ptr_new(__func__);
+ BLI_smallhash_init(&visithash);
+ STACK_INIT(stack);
+
maxindex = 0;
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
- if (BLI_ghash_haskey(visithash, e)) {
+ if (BLI_smallhash_haskey(&visithash, (uintptr_t)e)) {
continue;
}
- /* Prime the stack with this unvisited edge */
- BLI_array_append(stack, e);
-
/* Considering only edges and faces incident on vertex v, walk
* the edges & faces and assign an index to each connected set */
- while ((e = BLI_array_pop(stack))) {
- BLI_ghash_insert(visithash, e, SET_INT_IN_POINTER(maxindex));
+ do {
+ BLI_smallhash_insert(&visithash, (uintptr_t)e, SET_INT_IN_POINTER(maxindex));
- BM_ITER_ELEM (l, &liter, e, BM_LOOPS_OF_EDGE) {
- l_new = (l->v == v) ? l->prev : l->next;
- if (!BLI_ghash_haskey(visithash, l_new->e)) {
- BLI_array_append(stack, l_new->e);
- }
+ if (e->l) {
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = e->l;
+ do {
+ l_new = (l_iter->v == v) ? l_iter->prev : l_iter->next;
+ if (!BLI_smallhash_haskey(&visithash, (uintptr_t)l_new->e)) {
+ STACK_PUSH(stack, l_new->e);
+ }
+ } while ((l_iter = l_iter->radial_next) != l_first);
}
- }
+ } while ((e = STACK_POP(stack)));
maxindex++;
}
/* Make enough verts to split v for each group */
- verts = MEM_callocN(sizeof(BMVert *) * maxindex, __func__);
+ if (r_vout != NULL) {
+ verts = MEM_callocN(sizeof(BMVert *) * maxindex, __func__);
+ }
+ else {
+ verts = BLI_array_alloca(verts, maxindex);
+ }
+
verts[0] = v;
for (i = 1; i < maxindex; i++) {
verts[i] = BM_vert_create(bm, v->co, v, 0);
@@ -1961,23 +1979,23 @@
* by modifying data it loops over [#30632], this re-uses the 'stack' variable which is a bit
* bad practice but save alloc'ing a new array - note, the comment above is useful, keep it
* if you are tidying up code - campbell */
- BLI_array_empty(stack);
+ STACK_INIT(stack);
BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
if (l->v == v) {
- BLI_array_append(stack, (BMEdge *)l);
+ STACK_PUSH(stack, (BMEdge *)l);
}
}
- while ((l = (BMLoop *)(BLI_array_pop(stack)))) {
- if ((i = GET_INT_FROM_POINTER(BLI_ghash_lookup(visithash, l->e)))) {
+ while ((l = (BMLoop *)(STACK_POP(stack)))) {
+ if ((i = GET_INT_FROM_POINTER(BLI_smallhash_lookup(&visithash, (uintptr_t)l->e)))) {
l->v = verts[i];
}
}
#endif
- BLI_array_free(stack);
+ STACK_FREE(stack);
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
- i = GET_INT_FROM_POINTER(BLI_ghash_lookup(visithash, e));
+ i = GET_INT_FROM_POINTER(BLI_smallhash_lookup(&visithash, (uintptr_t)e));
if (i == 0) {
continue;
}
@@ -1988,7 +2006,7 @@
bmesh_disk_edge_append(e, verts[i]);
}
- BLI_ghash_free(visithash, NULL, NULL);
+ BLI_smallhash_release(&visithash);
for (i = 0; i < maxindex; i++) {
BM_CHECK_ELEMENT(verts[i]);
@@ -2001,10 +2019,12 @@
if (r_vout != NULL) {
*r_vout = verts;
}
- else {
- MEM_freeN(verts);
- }
+#undef STACK_INIT
+#undef STACK_PUSH
+#undef STACK_POP
+#undef STACK_FREE
+
return true;
}
More information about the Bf-blender-cvs
mailing list