[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