[Bf-blender-cvs] [8346bcf] bmesh-boolean-experiment: Use memarena to avoid too many stack allocations
Campbell Barton
noreply at git.blender.org
Thu Dec 10 11:06:55 CET 2015
Commit: 8346bcfaf4e257797a45a13cf2707ff63240cca0
Author: Campbell Barton
Date: Thu Dec 10 20:49:55 2015 +1100
Branches: bmesh-boolean-experiment
https://developer.blender.org/rB8346bcfaf4e257797a45a13cf2707ff63240cca0
Use memarena to avoid too many stack allocations
===================================================================
M source/blender/bmesh/intern/bmesh_polygon_edgenet.c
M source/blender/bmesh/intern/bmesh_polygon_edgenet.h
M source/blender/bmesh/tools/bmesh_intersect.c
===================================================================
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
index 30110ab..38127fb 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
@@ -29,6 +29,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
+#include "BLI_memarena.h"
#include "BLI_array.h"
#include "BLI_alloca.h"
#include "BLI_stackdefines.h"
@@ -934,10 +935,14 @@ static int bm_face_split_edgenet_find_connection(
/**
* For when the edge-net has holes in it-this connects them.
+ *
+ * \param mem_arena: Avoids many small allocs & should be cleared after each use.
+ * take care since \a r_edge_net_new is stored in \a r_edge_net_new.
*/
bool BM_face_split_edgenet_connect_islands(
BMesh *bm,
BMFace *f, BMEdge **edge_net_init, const unsigned int edge_net_init_len,
+ MemArena *mem_arena,
BMEdge ***r_edge_net_new, unsigned int *r_edge_net_new_len)
{
/* -------------------------------------------------------------------- */
@@ -947,6 +952,9 @@ bool BM_face_split_edgenet_connect_islands(
* - Connect the holes with edges (if any are found).
*
* Keep the first part fast since it will run very often for edge-nets that have no holes.
+ *
+ * \note Don't use the mem_arena unless he have holes to fill.
+ * (avoid thrashing the area when the initial check isn't so intensive on the stack).
*/
const unsigned int edge_arr_len = (unsigned int)edge_net_init_len + (unsigned int)f->len;
@@ -1050,7 +1058,7 @@ bool BM_face_split_edgenet_connect_islands(
#define VERT_IN_ARRAY BM_ELEM_INTERNAL_TAG
- struct EdgeGroupIsland **group_arr = BLI_array_alloca(group_arr, group_arr_len);
+ struct EdgeGroupIsland **group_arr = BLI_memarena_alloc(mem_arena, sizeof(*group_arr) * group_arr_len);
unsigned int vert_arr_len = 0;
/* sort groups by lowest value vertex */
{
@@ -1093,11 +1101,11 @@ bool BM_face_split_edgenet_connect_islands(
qsort(group_arr, group_arr_len, sizeof(*group_arr), group_min_cmp_fn);
/* we don't know how many unique verts there are connecting the edges, so over-alloc */
- BMVert **vert_arr = BLI_array_alloca(vert_arr, vert_arr_len);
+ BMVert **vert_arr = BLI_memarena_alloc(mem_arena, sizeof(*vert_arr) * vert_arr_len);
/* map vertex -> group index */
- unsigned int *verts_group_table = BLI_array_alloca(verts_group_table, vert_arr_len);
+ unsigned int *verts_group_table = BLI_memarena_alloc(mem_arena, sizeof(*verts_group_table) * vert_arr_len);
- float (*vert_coords_backup)[3] = BLI_array_alloca(vert_coords_backup, vert_arr_len);
+ float (*vert_coords_backup)[3] = BLI_memarena_alloc(mem_arena, sizeof(*vert_coords_backup) * vert_arr_len);
{
float axis_mat[3][3];
@@ -1157,7 +1165,7 @@ bool BM_face_split_edgenet_connect_islands(
/* may be an over-alloc, but not by much */
unsigned int edge_net_new_len = (unsigned int)edge_net_init_len + ((group_arr_len - 1) * 2);
- BMEdge **edge_net_new = MEM_mallocN(sizeof(*edge_net_new) * edge_net_new_len, __func__);
+ BMEdge **edge_net_new = BLI_memarena_alloc(mem_arena, sizeof(*edge_net_new) * edge_net_new_len);
memcpy(edge_net_new, edge_net_init, sizeof(*edge_net_new) * (size_t)edge_net_init_len);
{
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.h b/source/blender/bmesh/intern/bmesh_polygon_edgenet.h
index a1ea1cb..b664231 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.h
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.h
@@ -33,6 +33,8 @@ bool BM_face_split_edgenet(
bool BM_face_split_edgenet_connect_islands(
BMesh *bm,
BMFace *f, BMEdge **edge_net_init, const unsigned int edge_net_init_len,
- BMEdge ***r_edge_net_new, unsigned int *r_edge_net_new_len);
+ struct MemArena *arena,
+ BMEdge ***r_edge_net_new, unsigned int *r_edge_net_new_len)
+ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3, 5, 6, 7);
#endif /* __BMESH_POLYGON_EDGENET_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c
index 486c425..6930c48 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.c
+++ b/source/blender/bmesh/tools/bmesh_intersect.c
@@ -255,14 +255,12 @@ static void face_edges_add(
static void face_edges_split(
BMesh *bm,
BMFace *f,
- struct LinkBase *e_ls_base)
+ struct LinkBase *e_ls_base,
+ MemArena *mem_arena_edgenet)
{
unsigned int i;
unsigned int edge_arr_len = e_ls_base->list_len;
BMEdge **edge_arr = BLI_array_alloca(edge_arr, edge_arr_len);
-#ifdef USE_HOLE_FILL
- bool edge_arr_free = false;
-#endif
LinkNode *node;
BLI_assert(f->head.htype == BM_FACE);
@@ -282,22 +280,16 @@ static void face_edges_split(
if (BM_face_split_edgenet_connect_islands(
bm, f,
edge_arr, edge_arr_len,
+ mem_arena_edgenet,
&edge_arr_holes, &edge_arr_holes_len))
{
edge_arr_len = edge_arr_holes_len;
- edge_arr = edge_arr_holes;
- edge_arr_free = true;
+ edge_arr = edge_arr_holes; /* owned by the arena */
}
}
#endif
BM_face_split_edgenet(bm, f, edge_arr, (int)edge_arr_len, NULL, NULL);
-
-#ifdef USE_HOLE_FILL
- if (edge_arr_free) {
- MEM_freeN(edge_arr);
- }
-#endif
}
#endif
@@ -1563,6 +1555,8 @@ bool BM_mesh_intersect(
GHashIterator gh_iter;
BMFace **faces;
+ MemArena *mem_arena_edgenet = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+
faces = bm->ftable;
GHASH_ITER (gh_iter, s.face_edges) {
@@ -1579,8 +1573,12 @@ bool BM_mesh_intersect(
BLI_assert(BM_elem_index_get(f) == f_index);
- face_edges_split(bm, f, e_ls_base);
+ face_edges_split(bm, f, e_ls_base, mem_arena_edgenet);
+
+ BLI_memarena_clear(mem_arena_edgenet);
}
+
+ BLI_memarena_free(mem_arena_edgenet);
}
#endif /* USE_NET */
(void)totface_orig;
More information about the Bf-blender-cvs
mailing list