[Bf-blender-cvs] [4352980b0fb] temp_bmesh_multires: Dyntopo

Joseph Eagar noreply at git.blender.org
Wed May 19 23:38:00 CEST 2021


Commit: 4352980b0fba00206e6e935cb2070d399f328b0a
Author: Joseph Eagar
Date:   Wed May 19 14:36:00 2021 -0700
Branches: temp_bmesh_multires
https://developer.blender.org/rB4352980b0fba00206e6e935cb2070d399f328b0a

Dyntopo

* Got threaded mesh->bmesh conversion working (it's disabled
  pending further testing however).

Note that SCULPT_dynamic_topology_enable_ex calls BKE_scene_graph_update_tagged,
which in tests was adding ~1 second to conversion time for larger
meshes.  Do we need this call?

===================================================================

M	source/blender/blenlib/BLI_mempool.h
M	source/blender/blenlib/intern/BLI_mempool.c
M	source/blender/bmesh/intern/bmesh_mesh_convert_threaded.c
M	source/blender/editors/sculpt_paint/sculpt_dyntopo.c

===================================================================

diff --git a/source/blender/blenlib/BLI_mempool.h b/source/blender/blenlib/BLI_mempool.h
index 65f60071771..6109a216d95 100644
--- a/source/blender/blenlib/BLI_mempool.h
+++ b/source/blender/blenlib/BLI_mempool.h
@@ -93,7 +93,6 @@ BLI_mempool_iter *BLI_mempool_iter_threadsafe_create(BLI_mempool *pool,
     ATTR_NONNULL();
 void BLI_mempool_iter_threadsafe_free(BLI_mempool_iter *iter_arr) ATTR_NONNULL();
 
-
 /*
 This preallocates a mempool suitable for threading.  totelem elements are preallocated
 in chunks of size pchunk, and returned in r_chunks.
@@ -104,6 +103,7 @@ BLI_mempool *BLI_mempool_create_for_tasks(const unsigned int esize,
                                           const unsigned int pchunk,
                                           void ***r_chunks,
                                           unsigned int *r_totchunk,
+                                          unsigned int *r_esize,
                                           unsigned int flag);
 
 #ifdef __cplusplus
diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c
index 99c2e78e360..6acd654ce31 100644
--- a/source/blender/blenlib/intern/BLI_mempool.c
+++ b/source/blender/blenlib/intern/BLI_mempool.c
@@ -261,12 +261,34 @@ BLI_mempool *BLI_mempool_create_for_tasks(const unsigned int esize,
                                           const unsigned int pchunk,
                                           void ***r_chunks,
                                           unsigned int *r_totchunk,
+                                          unsigned int *r_esize,
                                           unsigned int flag)
 {
-  BLI_mempool *pool = BLI_mempool_create(esize, totelem, pchunk, flag);
+  BLI_mempool *pool = BLI_mempool_create(esize, 0, pchunk, flag);
 
-  BLI_mempool_chunk **chunks = MEM_callocN(sizeof(void *) * pool->maxchunks,
-                                           "BLI_mempool_create_for_tasks r_chunks");
+  // override pchunk, may not be a power of 2
+  pool->pchunk = pchunk;
+  pool->csize = pchunk * pool->esize;
+
+  if (totelem % pchunk == 0) {
+    pool->maxchunks = totelem / pchunk;
+  }
+  else {
+    pool->maxchunks = totelem / pchunk + 1;
+  }
+
+  if (totelem) {
+    BLI_freenode *last_tail = NULL;
+
+    /* Allocate the actual chunks. */
+    for (int i = 0; i < pool->maxchunks; i++) {
+      BLI_mempool_chunk *mpchunk = mempool_chunk_alloc(pool);
+      last_tail = mempool_chunk_add(pool, mpchunk, last_tail);
+    }
+  }
+
+  void **chunks = MEM_callocN(sizeof(void *) * pool->maxchunks,
+                              "BLI_mempool_create_for_tasks r_chunks");
 
   unsigned int totalloc = 0;
   *r_totchunk = 0;
@@ -274,9 +296,9 @@ BLI_mempool *BLI_mempool_create_for_tasks(const unsigned int esize,
   BLI_mempool_chunk *chunk = pool->chunks, *lastchunk = NULL;
 
   while (chunk) {
-    chunk = chunk->next;
-    totalloc += pool->pchunk;
     lastchunk = chunk;
+    totalloc += pool->pchunk;
+    chunk = chunk->next;
   }
 
   pool->totused = totalloc;
@@ -307,6 +329,7 @@ BLI_mempool *BLI_mempool_create_for_tasks(const unsigned int esize,
     BLI_mempool_free(pool, elem);
 
     totalloc--;
+    i--;
   }
 
   unsigned int ci = 0;
@@ -322,6 +345,8 @@ BLI_mempool *BLI_mempool_create_for_tasks(const unsigned int esize,
   }
 
   *r_totchunk = ci;
+  *r_chunks = (void **)chunks;
+  *r_esize = pool->esize;
 
   return pool;
 }
diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert_threaded.c b/source/blender/bmesh/intern/bmesh_mesh_convert_threaded.c
index 04d92990b35..0f7ea38c3c0 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_convert_threaded.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_convert_threaded.c
@@ -1,4 +1,4 @@
-#if 0
+#if 1
 #  include "DNA_key_types.h"
 #  include "DNA_mesh_types.h"
 #  include "DNA_meshdata_types.h"
@@ -8,8 +8,10 @@
 #  include "MEM_guardedalloc.h"
 
 #  include "BLI_alloca.h"
+#  include "BLI_compiler_attrs.h"
 #  include "BLI_listbase.h"
 #  include "BLI_math_vector.h"
+#  include "BLI_task.h"
 
 #  include "BKE_customdata.h"
 #  include "BKE_mesh.h"
@@ -36,45 +38,78 @@
 typedef struct BMThreadData {
   BMesh *bm;
   Object *ob;
-  Mesh *me;
+  const Mesh *me;
 
   struct BMeshFromMeshParams *params;
 
   void **vdata, **edata, **ldata, **fdata;
   int totdv, totde, totdl, totdf;
+  int vsize, esize, lsize, fsize;
+
+  int vchunk, echunk, lchunk, fchunk;
 
   BMVert **verts;
   BMEdge **edges;
   BMLoop **loops;
   BMFace **faces;
 
+  float (**shape_key_table)[3];
+  int tot_shape_keys;
+
+  int cd_vert_bweight;
+  int cd_edge_bweight;
+  int cd_crease;
+
+  int cdvsize, cdesize, cdlsize, cdfsize;
+
   // chunk sizes
   int totcv, totce, totcl, totcf;
 } BMThreadData;
 
-void bm_vert_task(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
+#  define ELEM_NEXT(type, ptr, size) ((type *)(((char *)ptr) + size))
+
+ATTR_NO_OPT void bm_vert_task(void *__restrict userdata,
+                              const int n,
+                              const TaskParallelTLS *__restrict tls)
 {
   BMThreadData *data = userdata;
   BMesh *bm = data->bm;
-  Mesh *me = data->me;
+  const Mesh *me = data->me;
 
-  int starti = n * data->totcv;
+  int starti = n * VCHUNK;
 
-  int ilen = starti + data->totcv > bm->totvert ? bm->totvert - starti : data->totcv;
+  int ilen = starti + VCHUNK > bm->totvert ? bm->totvert - starti : VCHUNK;
   MVert *mv = me->mvert + starti;
   BMVert *v = data->verts[n];
+  char *cdblock = data->vdata ? (char *)data->vdata[n] : NULL;
 
-  for (i = 0; i < ilen; i++, mv++, v++) {
-    v->head.data = NULL;
+  for (int i = 0; i < ilen; i++, mv++) {
+    if (cdblock) {
+      v->head.data = (void *)cdblock;
+      cdblock += data->cdvsize;
+    }
+    else {
+      v->head.data = NULL;
+    }
 
     v->head.htype = BM_VERT;
-    v->head.hflag = 0;
+    v->head.hflag = BM_vert_flag_from_mflag(mv->flag);
     v->head.api_flag = 0;
 
     copy_v3_v3(v->co, mv->co);
     normal_short_to_float_v3(v->no, mv->no);
 
     v->e = NULL;
+    v->head.index = i + starti;
+    v = ELEM_NEXT(BMVert, v, data->vsize);
+  }
+
+  if (data->vdata) {
+    v = data->verts[n];
+    for (int i = 0; i < ilen; i++) {
+      CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i + starti, &v->head.data, true);
+      v = ELEM_NEXT(BMVert, v, data->vsize);
+    }
   }
 }
 
@@ -82,36 +117,207 @@ void bm_edge_task(void *__restrict userdata, const int n, const TaskParallelTLS
 {
   BMThreadData *data = userdata;
   BMesh *bm = data->bm;
-  Mesh *me = data->me;
+  const Mesh *me = data->me;
 
-  int starti = n * data->totce;
+  int starti = n * ECHUNK;
 
-  int ilen = starti + data->totce > bm->totedge ? bm->totedge - starti : data->totce;
+  int ilen = starti + ECHUNK > bm->totedge ? bm->totedge - starti : ECHUNK;
   MEdge *med = me->medge + starti;
-  BMEdge *e = data->verts[n];
+  BMEdge *e = data->edges[n];
+  char *cdblock = data->edata ? (char *)data->edata[n] : NULL;
 
-  for (i = 0; i < ilen; i++, med++, e++) {
-    e->head.data = NULL;
+  for (int i = 0; i < ilen; i++, med++) {
+    if (cdblock) {
+      e->head.data = (void *)cdblock;
+      cdblock += data->cdesize;
+    }
+    else {
+      e->head.data = NULL;
+    }
 
     e->head.htype = BM_EDGE;
-    e->head.hflag = 0;
+    e->head.hflag = BM_edge_flag_from_mflag(med->flag);
     e->head.api_flag = 0;
 
-    e->v1 = &data->verts[med->v1 / data->totcv][med->v1 % data->totcv];
-    e->v2 = &data->verts[med->v2 / data->totcv][med->v2 % data->totcv];
+    e->v1 = &data->verts[med->v1 / VCHUNK][med->v1 % VCHUNK];
+    e->v2 = &data->verts[med->v2 / VCHUNK][med->v2 % VCHUNK];
 
     e->l = NULL;
+    e->v1_disk_link.next = e->v1_disk_link.prev = NULL;
+    e->v2_disk_link.next = e->v2_disk_link.prev = NULL;
+
+    e = ELEM_NEXT(BMEdge, e, data->esize);
+  }
+
+  if (data->edata) {
+    e = data->edges[n];
+    for (int i = 0; i < ilen; i++) {
+      CustomData_to_bmesh_block(&me->edata, &bm->edata, i + starti, &e->head.data, true);
+      e = ELEM_NEXT(BMEdge, e, data->esize);
+    }
+  }
+}
+
+void bm_loop_task(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
+{
+  BMThreadData *data = userdata;
+  BMesh *bm = data->bm;
+  const Mesh *me = data->me;
+
+  int starti = n * LCHUNK;
+
+  int ilen = starti + LCHUNK > bm->totloop ? bm->totloop - starti : LCHUNK;
+  MLoop *ml = me->mloop + starti;
+  BMLoop *l = data->loops[n];
+  char *cdblock = data->ldata ? (char *)data->ldata[n] : NULL;
+
+  for (int i = 0; i < ilen; i++, ml++) {
+    if (cdblock) {
+      l->head.data = (void *)cdblock;
+      cdblock += data->cdlsize;
+    }
+    else {
+      l->head.data = NULL;
+    }
+
+    l->head.htype = BM_LOOP;
+    l->head.hflag = 0;
+    l->head.api_flag = 0;
+
+    l->v = data->verts[ml->v / VCHUNK] + (ml->v % VCHUNK);
+    l->e = data->edges[ml->e / ECHUNK] + (ml->e % ECHUNK);
+    l->radial_next = l->radial_prev = l->next = l->prev = NULL;
+    l->f = NULL;
+
+    l = ELEM_NEXT(BMLoop, l, data->lsize);
+  }
+
+  if (data->ldata) {
+    l = data->loops[n];
+    for (int i = 0; i < ilen; i++) {
+      CustomData_to_bmesh_block(&me->ldata, &bm->ldata, i + starti, &l->head.data, true);
+      l = ELEM_NEXT(BMLoop, l, data->lsize);
+    }
+  }
+}
+
+void bm_face_task(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
+{
+  BMThreadData *data = userdata;
+  BMesh *bm = data->bm;
+  const Mesh *me = data->me;
+
+  int starti = n * FCHUNK;
+
+  int ilen = starti + FCHUNK > bm->totface ? bm->totface - starti : FCHUNK;
+  MPoly *mp = me->mpoly + starti;
+  BMFace *f = data->faces[n];
+  char *cdblock = data->fdata ? (char *)data->fdata[n] : NULL;
+
+  for (int i = 0; i < ilen; i++, mp++) {
+    if (cdblock) {
+      f->head.data = (void *)cdblock;
+      cdblock += data->cdfsize;
+    }
+    else {
+      f->head.data = NULL;
+    }
+
+    f->head.htype = BM_FACE;
+    f->head.hflag = BM_face_flag_from_mflag(mp->flag);
+    f->head.api_flag = 0;
+
+    f->len = mp->totloop;
+    f->mat_nr = mp->mat_nr;
+    zero_v3(f->no);
+
+    int li = mp->loopstart;
+    BMLoop *lastl = NULL;
+
+    for (int j = 0; j < mp->totloop; j++, li++) {
+      BMLoop *l = data->loops[li / 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list