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;

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to