Sculpt: Continue individual edge locks experiemnt
This commit is contained in:
parent
5de8134abc
commit
6e74907f4f
|
@ -601,11 +601,11 @@ static void armature_deform_coords_impl(const Object *ob_arm,
|
|||
BLI_parallel_mempool_settings_defaults(&settings);
|
||||
|
||||
if (use_dverts) {
|
||||
BLI_task_parallel_mempool(
|
||||
BM_task_parallel_mempool(
|
||||
em_target->bm->vpool, &data, armature_vert_task_editmesh, &settings);
|
||||
}
|
||||
else {
|
||||
BLI_task_parallel_mempool(
|
||||
BM_task_parallel_mempool(
|
||||
em_target->bm->vpool, &data, armature_vert_task_editmesh_no_dvert, &settings);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3980,7 +3980,12 @@ void CustomData_bmesh_init_pool_ex(CustomData *data,
|
|||
|
||||
/* If there are no layers, no pool is needed just yet */
|
||||
if (data->totlayer) {
|
||||
#ifndef BM_LOCKFREE_MEMPOOL
|
||||
data->pool = BLI_mempool_create_ex(data->totsize, totelem, chunksize, BLI_MEMPOOL_NOP, memtag);
|
||||
#else
|
||||
data->pool = (BLI_mempool *)BM_mempool_create(
|
||||
data->totsize, totelem, chunksize, BLI_MEMPOOL_NOP);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4068,7 +4073,7 @@ bool CustomData_bmesh_merge(const CustomData *source,
|
|||
}
|
||||
|
||||
if (destold.pool) {
|
||||
BLI_mempool_destroy(destold.pool);
|
||||
BM_mempool_destroy(destold.pool);
|
||||
}
|
||||
if (destold.layers) {
|
||||
MEM_freeN(destold.layers);
|
||||
|
@ -4096,7 +4101,7 @@ void CustomData_bmesh_free_block(CustomData *data, void **block)
|
|||
}
|
||||
|
||||
if (data->totsize) {
|
||||
BLI_mempool_free(data->pool, *block);
|
||||
BM_mempool_free((BM_mempool *)data->pool, *block);
|
||||
}
|
||||
|
||||
*block = NULL;
|
||||
|
@ -4137,7 +4142,7 @@ static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
|
|||
}
|
||||
|
||||
if (data->totsize > 0) {
|
||||
*block = BLI_mempool_alloc(data->pool);
|
||||
*block = BM_mempool_alloc((BM_mempool *)data->pool);
|
||||
|
||||
CustomData_bmesh_asan_poison(data, *block);
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#define DYNTOPO_EDGE_LOCKS
|
||||
//#define DYNTOPO_REPORT
|
||||
//#define WITH_ADAPTIVE_CURVATURE
|
||||
|
||||
|
@ -196,11 +195,11 @@ static bool bm_elem_is_free(BMElem *elem, int htype);
|
|||
extern char dyntopop_node_idx_layer_id[];
|
||||
extern char dyntopop_faces_areas_layer_id[];
|
||||
|
||||
#ifdef DYNTOPO_EDGE_LOCKS
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
|
||||
char *cdlayer_lock_attr_name = "__bm_lock";
|
||||
|
||||
static int cdlayer_lock_begin(PBVH *pbvh, BMesh *bm)
|
||||
ATTR_NO_OPT static int cdlayer_lock_begin(PBVH *pbvh, BMesh *bm)
|
||||
{
|
||||
int idx = CustomData_get_named_layer_index(&bm->edata, CD_PROP_INT32, cdlayer_lock_attr_name);
|
||||
|
||||
|
@ -208,7 +207,7 @@ static int cdlayer_lock_begin(PBVH *pbvh, BMesh *bm)
|
|||
BM_data_layer_add_named(bm, &bm->edata, CD_PROP_INT32, cdlayer_lock_attr_name);
|
||||
|
||||
idx = CustomData_get_named_layer_index(&bm->edata, CD_PROP_INT32, cdlayer_lock_attr_name);
|
||||
bm->vdata.layers[idx].flag |= CD_FLAG_TEMPORARY | CD_FLAG_ELEM_NOCOPY | CD_FLAG_ELEM_NOINTERP;
|
||||
bm->edata.layers[idx].flag |= CD_FLAG_TEMPORARY | CD_FLAG_ELEM_NOCOPY | CD_FLAG_ELEM_NOINTERP;
|
||||
|
||||
pbvh->cd_vert_node_offset = CustomData_get_named_layer_index(
|
||||
&pbvh->bm->vdata, CD_PROP_INT32, dyntopop_node_idx_layer_id);
|
||||
|
@ -219,13 +218,17 @@ static int cdlayer_lock_begin(PBVH *pbvh, BMesh *bm)
|
|||
pbvh->cd_face_node_offset = bm->pdata.layers[pbvh->cd_face_node_offset].offset;
|
||||
}
|
||||
|
||||
return bm->vdata.layers[idx].offset;
|
||||
return bm->edata.layers[idx].offset;
|
||||
}
|
||||
|
||||
static bool cdlayer_elem_lock(BMElem *elem, int cd_lock, int thread_nr)
|
||||
ATTR_NO_OPT static bool cdlayer_elem_lock(BMElem *elem, int cd_lock, int thread_nr)
|
||||
{
|
||||
thread_nr++;
|
||||
|
||||
if (bm_elem_is_free(elem, BM_EDGE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int *lock = BM_ELEM_CD_GET_VOID_P(elem, cd_lock);
|
||||
int old = *lock;
|
||||
|
||||
|
@ -233,9 +236,16 @@ static bool cdlayer_elem_lock(BMElem *elem, int cd_lock, int thread_nr)
|
|||
return true;
|
||||
}
|
||||
|
||||
while (old != atomic_cas_int32(lock, old, thread_nr)) {
|
||||
if (elem->head.htype != BM_EDGE) {
|
||||
// element was freed
|
||||
int i = 0;
|
||||
|
||||
while (old > 0 || old != atomic_cas_int32(lock, old, thread_nr)) {
|
||||
if (bm_elem_is_free(elem, BM_EDGE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
old = *lock;
|
||||
|
||||
if (i++ > 100000) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -253,16 +263,15 @@ static void cdlayer_elem_unlock(BMElem *elem, int cd_lock, int thread_nr)
|
|||
*lock = 0;
|
||||
}
|
||||
|
||||
static bool cdlayer_lock_edge(BMEdge *e, int cd_lock, int thread_nr)
|
||||
ATTR_NO_OPT static bool cdlayer_lock_edge(BMEdge *e, int cd_lock, int thread_nr)
|
||||
{
|
||||
if (BM_ELEM_CD_GET_INT(e, cd_lock) == thread_nr + 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!cdlayer_elem_lock((BMElem *)e, cd_lock, thread_nr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BMEdge **es = NULL;
|
||||
BLI_array_staticdeclare(es, 32);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
BMVert *v = i ? e->v2 : e->v1;
|
||||
|
||||
|
@ -271,21 +280,52 @@ static bool cdlayer_lock_edge(BMEdge *e, int cd_lock, int thread_nr)
|
|||
BMLoop *l = e2->l;
|
||||
|
||||
if (!l) {
|
||||
cdlayer_elem_lock((BMElem *)e2, cd_lock, thread_nr);
|
||||
if (!cdlayer_elem_lock((BMElem *)e2, cd_lock, thread_nr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BLI_array_append(es, e2);
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
BMLoop *l2 = l;
|
||||
do {
|
||||
cdlayer_elem_lock((BMElem *)l2->e, cd_lock, thread_nr);
|
||||
if (BM_elem_is_free((BMElem *)l2, BM_LOOP)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!cdlayer_elem_lock((BMElem *)l2->e, cd_lock, thread_nr)) {
|
||||
return false;
|
||||
}
|
||||
BLI_array_append(es, l2->e);
|
||||
} while ((l2 = l2->next) != l);
|
||||
} while ((l = l->next) != e2->l);
|
||||
} while ((l = l->radial_next) != e2->l);
|
||||
|
||||
} while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
|
||||
}
|
||||
|
||||
BLI_array_free(es);
|
||||
return true;
|
||||
|
||||
error:
|
||||
for (int i = 0; i < BLI_array_len(es); i++) {
|
||||
if (!es[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// eliminate duplicates
|
||||
for (int j = i + 1; j < BLI_array_len(es); j++) {
|
||||
if (es[i] == es[j]) {
|
||||
es[j] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
cdlayer_elem_unlock((BMElem *)es[i], cd_lock, thread_nr);
|
||||
}
|
||||
|
||||
BLI_array_free(es);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void cdlayer_unlock_edge(BMEdge *e, int cd_lock, int thread_nr)
|
||||
|
@ -315,7 +355,7 @@ static void cdlayer_unlock_edge(BMEdge *e, int cd_lock, int thread_nr)
|
|||
do {
|
||||
l2->e->head.hflag &= ~tag;
|
||||
} while ((l2 = l2->next) != l);
|
||||
} while ((l = l->next) != e2->l);
|
||||
} while ((l = l->radial_next) != e2->l);
|
||||
|
||||
} while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
|
||||
}
|
||||
|
@ -339,7 +379,7 @@ static void cdlayer_unlock_edge(BMEdge *e, int cd_lock, int thread_nr)
|
|||
BLI_array_append(es, l2->e);
|
||||
}
|
||||
} while ((l2 = l2->next) != l);
|
||||
} while ((l = l->next) != e2->l);
|
||||
} while ((l = l->radial_next) != e2->l);
|
||||
|
||||
} while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
|
||||
}
|
||||
|
@ -352,6 +392,69 @@ static void cdlayer_unlock_edge(BMEdge *e, int cd_lock, int thread_nr)
|
|||
cdlayer_elem_unlock((BMElem *)e2, cd_lock, thread_nr);
|
||||
}
|
||||
}
|
||||
|
||||
BLI_array_free(es);
|
||||
}
|
||||
|
||||
static void cdlayer_unlock_vert(BMVert *v, int cd_lock, int thread_nr)
|
||||
{
|
||||
BMEdge **es = NULL;
|
||||
BLI_array_staticdeclare(es, 32);
|
||||
|
||||
if (!v->e) {
|
||||
return;
|
||||
}
|
||||
const int tag = BM_ELEM_TAG_ALT;
|
||||
|
||||
BMEdge *e2 = v->e;
|
||||
do {
|
||||
BMLoop *l = e2->l;
|
||||
if (!l) {
|
||||
e2->head.hflag &= ~tag;
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
BMLoop *l2 = l;
|
||||
do {
|
||||
l2->e->head.hflag &= ~tag;
|
||||
|
||||
} while ((l2 = l2->next) != l);
|
||||
} while ((l = l->radial_next) != e2->l);
|
||||
|
||||
} while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
|
||||
|
||||
e2 = v->e;
|
||||
do {
|
||||
BMLoop *l = e2->l;
|
||||
if (!l) {
|
||||
e2->head.hflag |= tag;
|
||||
BLI_array_append(es, e2);
|
||||
continue;
|
||||
}
|
||||
|
||||
do {
|
||||
BMLoop *l2 = l;
|
||||
do {
|
||||
if (!(l2->e->head.hflag & tag)) {
|
||||
l2->e->head.hflag |= tag;
|
||||
BLI_array_append(es, l2->e);
|
||||
}
|
||||
} while ((l2 = l2->next) != l);
|
||||
} while ((l = l->radial_next) != e2->l);
|
||||
|
||||
} while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
|
||||
|
||||
for (int i = 0; i < BLI_array_len(es); i++) {
|
||||
BMEdge *e2 = es[i];
|
||||
|
||||
if (!bm_elem_is_free((BMElem *)e2, BM_EDGE) &&
|
||||
BM_ELEM_CD_GET_INT(e2, cd_lock) == thread_nr + 1) {
|
||||
cdlayer_elem_unlock((BMElem *)e2, cd_lock, thread_nr);
|
||||
}
|
||||
}
|
||||
|
||||
BLI_array_free(es);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -982,6 +1085,10 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
|
|||
|
||||
BLI_assert((pbvh->totnode == 1 || node_index) && node_index <= pbvh->totnode);
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BLI_ticket_mutex_lock(node->lock);
|
||||
#endif
|
||||
|
||||
/* avoid initializing customdata because its quite involved */
|
||||
BMVert *v = BM_vert_create(pbvh->bm, co, NULL, BM_CREATE_NOP);
|
||||
MSculptVert *mv = BKE_PBVH_SCULPTVERT(pbvh->cd_sculpt_vert, v);
|
||||
|
@ -1019,6 +1126,10 @@ static BMVert *pbvh_bmesh_vert_create(PBVH *pbvh,
|
|||
BM_log_vert_added(pbvh->bm_log, v, cd_vert_mask_offset);
|
||||
v->head.index = pbvh->bm->totvert; // set provisional index
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BLI_ticket_mutex_unlock(node->lock);
|
||||
#endif
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
@ -1345,6 +1456,7 @@ static bool pbvh_bmesh_vert_relink(PBVH *pbvh, BMVert *v)
|
|||
|
||||
static void pbvh_bmesh_vert_remove(PBVH *pbvh, BMVert *v)
|
||||
{
|
||||
|
||||
/* never match for first time */
|
||||
int f_node_index_prev = DYNTOPO_NODE_NONE;
|
||||
const int updateflag = PBVH_UpdateDrawBuffers | PBVH_UpdateBB | PBVH_UpdateTris |
|
||||
|
@ -1353,6 +1465,10 @@ static void pbvh_bmesh_vert_remove(PBVH *pbvh, BMVert *v)
|
|||
PBVHNode *v_node = pbvh_bmesh_node_from_vert(pbvh, v);
|
||||
|
||||
if (v_node) {
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BLI_ticket_mutex_lock(v_node->lock);
|
||||
#endif
|
||||
|
||||
BLI_table_gset_remove(v_node->bm_unique_verts, v, NULL);
|
||||
v_node->flag |= updateflag;
|
||||
}
|
||||
|
@ -1374,12 +1490,23 @@ static void pbvh_bmesh_vert_remove(PBVH *pbvh, BMVert *v)
|
|||
f_node_index_prev = f_node_index;
|
||||
|
||||
PBVHNode *f_node = &pbvh->nodes[f_node_index];
|
||||
f_node->flag |= updateflag; // flag update of bm_other_verts
|
||||
// int flag = f_node->flag | updateflag;
|
||||
|
||||
// flag update of bm_other_verts
|
||||
// atomic_add_and_fetch_int32((int32_t *)(&f_node->flag), flag);
|
||||
|
||||
f_node->flag |= updateflag;
|
||||
|
||||
BLI_assert(!BLI_table_gset_haskey(f_node->bm_unique_verts, v));
|
||||
}
|
||||
}
|
||||
BM_FACES_OF_VERT_ITER_END;
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
if (v_node) {
|
||||
BLI_ticket_mutex_unlock(v_node->lock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void pbvh_bmesh_face_remove(
|
||||
|
@ -1388,11 +1515,15 @@ static void pbvh_bmesh_face_remove(
|
|||
PBVHNode *f_node = pbvh_bmesh_node_from_face(pbvh, f);
|
||||
|
||||
if (!f_node || !(f_node->flag & PBVH_Leaf)) {
|
||||
printf("pbvh corruption\n");
|
||||
printf("%s: pbvh corruption; node: %p\n", __func__, f_node);
|
||||
fflush(stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BLI_ticket_mutex_lock(f_node->lock);
|
||||
#endif
|
||||
|
||||
bm_logstack_push();
|
||||
|
||||
/* Check if any of this face's vertices need to be removed
|
||||
|
@ -1412,7 +1543,15 @@ static void pbvh_bmesh_face_remove(
|
|||
// BLI_assert(new_node || BM_vert_face_count_is_equal(v, 1));
|
||||
|
||||
if (new_node) {
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BLI_ticket_mutex_lock(new_node->lock);
|
||||
#endif
|
||||
|
||||
pbvh_bmesh_vert_ownership_transfer(pbvh, new_node, v);
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BLI_ticket_mutex_unlock(new_node->lock);
|
||||
#endif
|
||||
}
|
||||
else if (ensure_ownership_transfer && !BM_vert_face_count_is_equal(v, 1)) {
|
||||
pbvh_bmesh_vert_remove(pbvh, v);
|
||||
|
@ -1439,6 +1578,9 @@ static void pbvh_bmesh_face_remove(
|
|||
PBVH_UpdateOtherVerts;
|
||||
|
||||
bm_logstack_pop();
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BLI_ticket_mutex_unlock(f_node->lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BKE_pbvh_bmesh_remove_face(PBVH *pbvh, BMFace *f, bool log_face)
|
||||
|
@ -1913,7 +2055,7 @@ typedef struct EdgeQueueThreadData {
|
|||
int size;
|
||||
bool is_collapse;
|
||||
int seed;
|
||||
int n;
|
||||
int cd_lock;
|
||||
} EdgeQueueThreadData;
|
||||
|
||||
static void edge_thread_data_insert(EdgeQueueThreadData *tdata, BMEdge *e)
|
||||
|
@ -3702,7 +3844,7 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef DYNTOPO_EDGE_LOCKS
|
||||
#ifndef WITH_DYNTOPO_EDGE_LOCKS
|
||||
pbvh_check_vert_boundary(pbvh, v1);
|
||||
pbvh_check_vert_boundary(pbvh, v2);
|
||||
#endif
|
||||
|
@ -3713,7 +3855,7 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
|
||||
validate_edge(pbvh, pbvh->bm, e, true, true);
|
||||
|
||||
#ifndef DYNTOPO_EDGE_LOCKS
|
||||
#ifndef WITH_DYNTOPO_EDGE_LOCKS
|
||||
check_vert_fan_are_tris(pbvh, e->v1);
|
||||
check_vert_fan_are_tris(pbvh, e->v2);
|
||||
#endif
|
||||
|
@ -3954,7 +4096,7 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
BMLoop *l = e2->l;
|
||||
|
||||
if (e2 != e && !(e2->head.hflag & tag)) {
|
||||
#ifndef DYNTOPO_EDGE_LOCKS
|
||||
#ifndef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BM_log_edge_topo_pre(pbvh->bm_log, e2);
|
||||
#endif
|
||||
}
|
||||
|
@ -3968,7 +4110,7 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
do {
|
||||
if (BM_ELEM_CD_GET_INT(l->f, pbvh->cd_face_node_offset) != DYNTOPO_NODE_NONE) {
|
||||
pbvh_bmesh_face_remove(pbvh, l->f, false, false, false);
|
||||
#ifndef DYNTOPO_EDGE_LOCKS
|
||||
#ifndef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BM_log_face_topo_pre(pbvh->bm_log, l->f);
|
||||
#endif
|
||||
}
|
||||
|
@ -3978,7 +4120,7 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
|
||||
pbvh_bmesh_vert_remove(pbvh, v_del);
|
||||
|
||||
#ifndef DYNTOPO_EDGE_LOCKS
|
||||
#ifndef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BM_log_edge_topo_pre(pbvh->bm_log, e);
|
||||
BM_log_vert_removed(pbvh->bm_log, v_del, pbvh->cd_vert_mask_offset);
|
||||
#endif
|
||||
|
@ -4106,7 +4248,7 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
|
||||
if (e2->head.hflag & tag) {
|
||||
e2->head.hflag &= ~tag;
|
||||
#ifndef DYNTOPO_EDGE_LOCKS
|
||||
#ifndef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BM_log_edge_topo_post(pbvh->bm_log, e2);
|
||||
#endif
|
||||
}
|
||||
|
@ -4139,7 +4281,7 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
|
||||
if (!fbad && BM_ELEM_CD_GET_INT(l->f, pbvh->cd_face_node_offset) == DYNTOPO_NODE_NONE) {
|
||||
BKE_pbvh_bmesh_add_face(pbvh, l->f, false, false);
|
||||
#ifndef DYNTOPO_EDGE_LOCKS
|
||||
#ifndef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BM_log_face_topo_post(pbvh->bm_log, l->f);
|
||||
#endif
|
||||
}
|
||||
|
@ -4186,17 +4328,34 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
return v_conn;
|
||||
}
|
||||
|
||||
#ifdef DYNTOPO_EDGE_LOCKS
|
||||
static void pbvh_bmesh_collapse_short_edges_cb(void *__restrict userdata,
|
||||
const int n,
|
||||
const TaskParallelTLS *__restrict tls)
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
ATTR_NO_OPT static void pbvh_bmesh_collapse_short_edges_cb(void *__restrict userdata,
|
||||
const int n,
|
||||
const TaskParallelTLS *__restrict tls)
|
||||
{
|
||||
EdgeQueueThreadData *tdata = ((EdgeQueueThreadData *)userdata) + n;
|
||||
int thread_nr = n;
|
||||
const int thread_nr = n;
|
||||
const int cd_lock = tdata->cd_lock;
|
||||
|
||||
GHash *unused = BLI_ghash_ptr_new("unused");
|
||||
BLI_buffer_declare_static(BMFace *, deleted_faces, BLI_BUFFER_NOP, 32);
|
||||
|
||||
for (int i = 0; i < tdata->totedge; i++) {
|
||||
BMEdge *e = tdata->edges[i];
|
||||
|
||||
if (BM_elem_is_free((BMElem *)e, BM_EDGE) || !cdlayer_lock_edge(e, cd_lock, thread_nr)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BMVert *v_conn = pbvh_bmesh_collapse_edge(
|
||||
tdata->pbvh, e, e->v1, e->v2, unused, &deleted_faces, tdata->eq_ctx);
|
||||
if (v_conn) {
|
||||
cdlayer_unlock_vert(v_conn, cd_lock, thread_nr);
|
||||
}
|
||||
}
|
||||
|
||||
BLI_ghash_free(unused, NULL, NULL);
|
||||
BLI_buffer_free(&deleted_faces);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -4228,9 +4387,11 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
|
|||
BMVert **checkvs = NULL;
|
||||
BLI_array_declare(checkvs);
|
||||
|
||||
#ifdef DYNTOPO_EDGE_LOCKS
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
int cd_lock = cdlayer_lock_begin(pbvh, pbvh->bm);
|
||||
const int totthread = 8;
|
||||
EdgeQueueThreadData *tdata = MEM_callocN(sizeof(EdgeQueueThreadData), "EdgeQueueThreadData");
|
||||
EdgeQueueThreadData *tdata = MEM_callocN(sizeof(EdgeQueueThreadData) * totthread,
|
||||
"EdgeQueueThreadData");
|
||||
int totedge = max_steps / totthread + 1;
|
||||
|
||||
int curthread = 0;
|
||||
|
@ -4241,6 +4402,9 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
|
|||
|
||||
for (int i = 0; i < totthread; i++) {
|
||||
tdata[i].edges = MEM_mallocN(sizeof(void *) * totedge, "edge queue thread data edges");
|
||||
tdata[i].pbvh = pbvh;
|
||||
tdata[i].eq_ctx = eq_ctx;
|
||||
tdata[i].cd_lock = cd_lock;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -4295,7 +4459,7 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
|
|||
continue;
|
||||
}
|
||||
|
||||
#ifdef DYNTOPO_EDGE_LOCKS
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
tdata[curthread].edges[tdata[curthread].totedge++] = e;
|
||||
curthread = (curthread + 1) % totthread;
|
||||
#else
|
||||
|
@ -4335,9 +4499,11 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
TaskParallelSettings settings;
|
||||
|
||||
BLI_parallel_range_settings_defaults(&settings);
|
||||
settings.use_threading = true;
|
||||
BLI_task_parallel_range(0, totthread, tdata, pbvh_bmesh_collapse_short_edges_cb, &settings);
|
||||
|
||||
for (int i = 0; i < totthread; i++) {
|
||||
|
@ -4345,6 +4511,7 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
|
|||
}
|
||||
|
||||
MEM_SAFE_FREE(tdata);
|
||||
#endif
|
||||
|
||||
// add log subentry
|
||||
BM_log_entry_add_ex(pbvh->bm, pbvh->bm_log, true);
|
||||
|
@ -5911,6 +6078,9 @@ DynTopoState *BKE_dyntopo_init(BMesh *bm, PBVH *existing_pbvh)
|
|||
|
||||
node->flag = PBVH_Leaf | PBVH_UpdateTris | PBVH_UpdateTriAreas;
|
||||
node->bm_faces = BLI_table_gset_new_ex("node->bm_faces", bm->totface);
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
node->lock = BLI_ticket_mutex_alloc();
|
||||
#endif
|
||||
node->bm_unique_verts = BLI_table_gset_new_ex("node->bm_unique_verts", bm->totvert);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -405,11 +405,10 @@ static void lattice_deform_coords_impl(const Object *ob_lattice,
|
|||
BLI_parallel_mempool_settings_defaults(&settings);
|
||||
|
||||
if (cd_dvert_offset != -1) {
|
||||
BLI_task_parallel_mempool(
|
||||
em_target->bm->vpool, &data, lattice_vert_task_editmesh, &settings);
|
||||
BM_task_parallel_mempool(em_target->bm->vpool, &data, lattice_vert_task_editmesh, &settings);
|
||||
}
|
||||
else {
|
||||
BLI_task_parallel_mempool(
|
||||
BM_task_parallel_mempool(
|
||||
em_target->bm->vpool, &data, lattice_vert_task_editmesh_no_dvert, &settings);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -365,6 +365,11 @@ static void pbvh_bmesh_node_split(
|
|||
|
||||
c1->bm_other_verts = c2->bm_other_verts = NULL;
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
c1->lock = BLI_ticket_mutex_alloc();
|
||||
c2->lock = BLI_ticket_mutex_alloc();
|
||||
#endif
|
||||
|
||||
/* Partition the parent node's faces between the two children */
|
||||
TGSET_ITER (f, n->bm_faces) {
|
||||
const BBC *bbc = &bbc_array[BM_elem_index_get(f)];
|
||||
|
@ -543,6 +548,10 @@ void bke_pbvh_insert_face_finalize(PBVH *pbvh, BMFace *f, const int ni)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BLI_ticket_mutex_lock(node->lock);
|
||||
#endif
|
||||
|
||||
BLI_table_gset_add(node->bm_faces, f);
|
||||
|
||||
int updateflag = PBVH_UpdateTris | PBVH_UpdateBB | PBVH_UpdateDrawBuffers |
|
||||
|
@ -569,6 +578,9 @@ void bke_pbvh_insert_face_finalize(PBVH *pbvh, BMFace *f, const int ni)
|
|||
PBVHNode *node2 = pbvh->nodes + ni2;
|
||||
|
||||
if (ni != ni2) {
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BLI_ticket_mutex_lock(node2->lock);
|
||||
#endif
|
||||
BLI_table_gset_add(node->bm_other_verts, l->v);
|
||||
}
|
||||
|
||||
|
@ -576,9 +588,19 @@ void bke_pbvh_insert_face_finalize(PBVH *pbvh, BMFace *f, const int ni)
|
|||
|
||||
BB_expand(&node2->vb, l->v->co);
|
||||
BB_expand(&node2->orig_vb, mv->origco);
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
if (ni != ni2) {
|
||||
BLI_ticket_mutex_unlock(node2->lock);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
l = l->next;
|
||||
} while (l != f->l_first);
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BLI_ticket_mutex_unlock(node->lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
void bke_pbvh_insert_face(PBVH *pbvh, struct BMFace *f)
|
||||
|
@ -1387,6 +1409,10 @@ static void pbvh_bmesh_create_nodes_fast_recursive(
|
|||
n->flag = PBVH_Leaf | PBVH_UpdateTris;
|
||||
n->bm_faces = BLI_table_gset_new_ex("bm_faces", node->totface);
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
n->lock = BLI_ticket_mutex_alloc();
|
||||
#endif
|
||||
|
||||
/* Create vert hash sets */
|
||||
n->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
|
||||
n->bm_other_verts = BLI_table_gset_new("bm_other_verts");
|
||||
|
@ -2771,6 +2797,10 @@ static void BKE_pbvh_bmesh_correct_tree(PBVH *pbvh, PBVHNode *node, PBVHNode *pa
|
|||
node->bm_other_verts = BLI_table_gset_new("bm_other_verts");
|
||||
node->bm_faces = BLI_table_gset_new("bm_faces");
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
node->lock = BLI_ticket_mutex_alloc();
|
||||
#endif
|
||||
|
||||
pbvh_bmesh_join_subnodes(pbvh, pbvh->nodes + node->children_offset, node);
|
||||
pbvh_bmesh_join_subnodes(pbvh, pbvh->nodes + node->children_offset + 1, node);
|
||||
|
||||
|
@ -2855,6 +2885,10 @@ static void pbvh_bmesh_compact_tree(PBVH *bvh)
|
|||
n3->bm_other_verts = BLI_table_gset_new("bm_other_verts");
|
||||
n3->bm_faces = BLI_table_gset_new("bm_faces");
|
||||
n3->tribuf = NULL;
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
n3->lock = BLI_ticket_mutex_alloc();
|
||||
#endif
|
||||
}
|
||||
else if ((n1->flag & PBVH_Delete) && (n2->flag & PBVH_Delete)) {
|
||||
n->children_offset = 0;
|
||||
|
@ -2866,6 +2900,9 @@ static void pbvh_bmesh_compact_tree(PBVH *bvh)
|
|||
n->bm_other_verts = BLI_table_gset_new("bm_other_verts");
|
||||
n->bm_faces = BLI_table_gset_new("bm_faces");
|
||||
n->tribuf = NULL;
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
n->lock = BLI_ticket_mutex_alloc();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2981,6 +3018,9 @@ static void pbvh_bmesh_compact_tree(PBVH *bvh)
|
|||
n->bm_unique_verts = BLI_table_gset_new("bleh");
|
||||
n->bm_other_verts = BLI_table_gset_new("bleh");
|
||||
n->bm_faces = BLI_table_gset_new("bleh");
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
n->lock = BLI_ticket_mutex_alloc();
|
||||
#endif
|
||||
}
|
||||
|
||||
BMVert *v;
|
||||
|
@ -3257,6 +3297,9 @@ static void pbvh_bmesh_join_nodes(PBVH *bvh)
|
|||
n3->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
|
||||
n3->bm_other_verts = BLI_table_gset_new("bm_other_verts");
|
||||
n3->bm_faces = BLI_table_gset_new("bm_faces");
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
n3->lock = BLI_ticket_mutex_alloc();
|
||||
#endif
|
||||
n3->tribuf = NULL;
|
||||
}
|
||||
else if ((n1->flag & PBVH_Delete) && (n2->flag & PBVH_Delete)) {
|
||||
|
@ -3268,6 +3311,9 @@ static void pbvh_bmesh_join_nodes(PBVH *bvh)
|
|||
n->bm_unique_verts = BLI_table_gset_new("bm_unique_verts");
|
||||
n->bm_other_verts = BLI_table_gset_new("bm_other_verts");
|
||||
n->bm_faces = BLI_table_gset_new("bm_faces");
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
n->lock = BLI_ticket_mutex_alloc();
|
||||
#endif
|
||||
n->tribuf = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -3384,6 +3430,9 @@ static void pbvh_bmesh_join_nodes(PBVH *bvh)
|
|||
n->bm_unique_verts = BLI_table_gset_new("bleh");
|
||||
n->bm_other_verts = BLI_table_gset_new("bleh");
|
||||
n->bm_faces = BLI_table_gset_new("bleh");
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
n->lock = BLI_ticket_mutex_alloc();
|
||||
#endif
|
||||
}
|
||||
|
||||
BMVert *v;
|
||||
|
@ -3565,18 +3614,18 @@ static void scan_edge_split(BMesh *bm, BMEdge **edges, int totedge)
|
|||
for (int i = 0; i < totedge; i++) {
|
||||
BMEdge *e = edges[i];
|
||||
|
||||
BMVert *v2 = BLI_mempool_alloc(bm->vpool);
|
||||
BMVert *v2 = BM_mempool_alloc(bm->vpool);
|
||||
memset(v2, 0, sizeof(*v2));
|
||||
v2->head.data = BLI_mempool_alloc(bm->vdata.pool);
|
||||
v2->head.data = (BLI_mempool *)BM_mempool_alloc((BM_mempool *)bm->vdata.pool);
|
||||
|
||||
BLI_array_append(newverts, v2);
|
||||
|
||||
BMEdge *e2 = BLI_mempool_alloc(bm->epool);
|
||||
BMEdge *e2 = BM_mempool_alloc(bm->epool);
|
||||
BLI_array_append(newedges, e2);
|
||||
|
||||
memset(e2, 0, sizeof(*e2));
|
||||
if (bm->edata.pool) {
|
||||
e2->head.data = BLI_mempool_alloc(bm->edata.pool);
|
||||
e2->head.data = (BLI_mempool *)BM_mempool_alloc((BM_mempool *)bm->edata.pool);
|
||||
}
|
||||
|
||||
BMLoop *l = e->l;
|
||||
|
@ -3587,7 +3636,7 @@ static void scan_edge_split(BMesh *bm, BMEdge **edges, int totedge)
|
|||
|
||||
do {
|
||||
BLI_array_append(faces, l->f);
|
||||
BMFace *f2 = BLI_mempool_alloc(bm->fpool);
|
||||
BMFace *f2 = BM_mempool_alloc(bm->fpool);
|
||||
|
||||
BLI_array_append(faces, l->f);
|
||||
BLI_array_append(fmap, v2);
|
||||
|
@ -3598,15 +3647,15 @@ static void scan_edge_split(BMesh *bm, BMEdge **edges, int totedge)
|
|||
BLI_array_append(emap, i);
|
||||
|
||||
memset(f2, 0, sizeof(*f2));
|
||||
f2->head.data = BLI_mempool_alloc(bm->ldata.pool);
|
||||
f2->head.data = (BLI_mempool *)BM_mempool_alloc((BM_mempool *)bm->ldata.pool);
|
||||
|
||||
BMLoop *prev = NULL;
|
||||
BMLoop *l2 = NULL;
|
||||
|
||||
for (int j = 0; j < 3; j++) {
|
||||
l2 = BLI_mempool_alloc(bm->lpool);
|
||||
l2 = BM_mempool_alloc(bm->lpool);
|
||||
memset(l2, 0, sizeof(*l2));
|
||||
l2->head.data = BLI_mempool_alloc(bm->ldata.pool);
|
||||
l2->head.data = (BLI_mempool *)BM_mempool_alloc((BM_mempool *)bm->ldata.pool);
|
||||
|
||||
l2->prev = prev;
|
||||
|
||||
|
@ -3829,13 +3878,13 @@ BMesh *BKE_pbvh_reorder_bmesh(PBVH *pbvh)
|
|||
}
|
||||
}
|
||||
|
||||
BLI_mempool_iter loopiter;
|
||||
BLI_mempool_iternew(pbvh->bm->lpool, &loopiter);
|
||||
BMLoop *l = BLI_mempool_iterstep(&loopiter);
|
||||
BM_mempool_iter loopiter;
|
||||
BM_mempool_iternew((BM_mempool *)pbvh->bm->lpool, &loopiter);
|
||||
BMLoop *l = BM_mempool_iterstep(&loopiter);
|
||||
BMEdge *e;
|
||||
BMFace *f;
|
||||
|
||||
for (i = 0; l; l = BLI_mempool_iterstep(&loopiter), i++) {
|
||||
for (i = 0; l; l = BM_mempool_iterstep(&loopiter), i++) {
|
||||
l->head.hflag &= ~flag;
|
||||
}
|
||||
BM_ITER_MESH (e, &iter, pbvh->bm, BM_EDGES_OF_MESH) {
|
||||
|
@ -3962,10 +4011,10 @@ BMesh *BKE_pbvh_reorder_bmesh(PBVH *pbvh)
|
|||
fidx[i] = (uint)f->head.index;
|
||||
}
|
||||
|
||||
BLI_mempool_iternew(pbvh->bm->lpool, &loopiter);
|
||||
l = BLI_mempool_iterstep(&loopiter);
|
||||
BM_mempool_iternew(pbvh->bm->lpool, &loopiter);
|
||||
l = BM_mempool_iterstep(&loopiter);
|
||||
|
||||
for (i = 0; l; l = BLI_mempool_iterstep(&loopiter), i++) {
|
||||
for (i = 0; l; l = BM_mempool_iterstep(&loopiter), i++) {
|
||||
// handle orphaned loops
|
||||
if (!(l->head.hflag & flag)) {
|
||||
printf("warning in %s: orphaned loop!\n", __func__);
|
||||
|
@ -4985,15 +5034,15 @@ void pbvh_bmesh_cache_test(CacheParams *params, BMesh **r_bm, PBVH **r_pbvh_out)
|
|||
.no_reuse_ids = false}));
|
||||
|
||||
// reinit pools
|
||||
BLI_mempool_destroy(bm->vpool);
|
||||
BLI_mempool_destroy(bm->epool);
|
||||
BLI_mempool_destroy(bm->lpool);
|
||||
BLI_mempool_destroy(bm->fpool);
|
||||
BM_mempool_destroy(bm->vpool);
|
||||
BM_mempool_destroy(bm->epool);
|
||||
BM_mempool_destroy(bm->lpool);
|
||||
BM_mempool_destroy(bm->fpool);
|
||||
|
||||
bm->vpool = BLI_mempool_create(sizeof(BMVert), 0, (int)params->vchunk, BLI_MEMPOOL_ALLOW_ITER);
|
||||
bm->epool = BLI_mempool_create(sizeof(BMEdge), 0, (int)params->echunk, BLI_MEMPOOL_ALLOW_ITER);
|
||||
bm->lpool = BLI_mempool_create(sizeof(BMLoop), 0, (int)params->lchunk, BLI_MEMPOOL_ALLOW_ITER);
|
||||
bm->fpool = BLI_mempool_create(sizeof(BMFace), 0, (int)params->pchunk, BLI_MEMPOOL_ALLOW_ITER);
|
||||
bm->vpool = BM_mempool_create(sizeof(BMVert), 0, (int)params->vchunk, BLI_MEMPOOL_ALLOW_ITER);
|
||||
bm->epool = BM_mempool_create(sizeof(BMEdge), 0, (int)params->echunk, BLI_MEMPOOL_ALLOW_ITER);
|
||||
bm->lpool = BM_mempool_create(sizeof(BMLoop), 0, (int)params->lchunk, BLI_MEMPOOL_ALLOW_ITER);
|
||||
bm->fpool = BM_mempool_create(sizeof(BMFace), 0, (int)params->pchunk, BLI_MEMPOOL_ALLOW_ITER);
|
||||
|
||||
GHash *vhash = BLI_ghash_ptr_new("vhash");
|
||||
|
||||
|
|
|
@ -38,6 +38,18 @@ typedef struct {
|
|||
float bmin[3], bmax[3], bcentroid[3];
|
||||
} BBC;
|
||||
|
||||
//#define WITH_DYNTOPO_EDGE_LOCKS
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
# ifndef BM_LOCKFREE_MEMPOOL
|
||||
# error \
|
||||
"Cannot have WITH_DYNTOPO_EDGE_LOCKS without BM_LOCKFREE_MEMPOOL (set it in bmesh_class.h)"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
# include "BLI_threads.h"
|
||||
#endif
|
||||
|
||||
/* NOTE: this structure is getting large, might want to split it into
|
||||
* union'd structs */
|
||||
struct PBVHNode {
|
||||
|
@ -99,7 +111,7 @@ struct PBVHNode {
|
|||
|
||||
/* Indicates whether this node is a leaf or not; also used for
|
||||
* marking various updates that need to be applied. */
|
||||
PBVHNodeFlags flag : 32;
|
||||
PBVHNodeFlags flag;
|
||||
|
||||
/* Used for raycasting: how close bb is to the ray point. */
|
||||
float tmin;
|
||||
|
@ -126,6 +138,10 @@ struct PBVHNode {
|
|||
#ifdef PROXY_ADVANCED
|
||||
ProxyVertArray proxyverts;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
TicketMutex *lock;
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -1,13 +1,42 @@
|
|||
#pragma once
|
||||
|
||||
#include "BLI_task.h"
|
||||
|
||||
typedef struct BLI_lfmempool {
|
||||
void *unused;
|
||||
} BLI_lfmempool;
|
||||
|
||||
typedef struct BLI_lfmempool_iter {
|
||||
void *chunk;
|
||||
BLI_lfmempool *pool;
|
||||
int i;
|
||||
void **curchunk_threaded_shared;
|
||||
} BLI_lfmempool_iter;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
BLI_lfmempool *BLI_lfmempool_create(int esize, int psize);
|
||||
void BLI_lfmempool_destroy(BLI_lfmempool *pool);
|
||||
void *BLI_lfmempool_alloc(BLI_lfmempool *pool);
|
||||
void *BLI_lfmempool_calloc(BLI_lfmempool *pool);
|
||||
void BLI_lfmempool_free(BLI_lfmempool *pool, void *mem);
|
||||
void BLI_lfmempool_iternew(BLI_lfmempool *_pool, BLI_lfmempool_iter *iter);
|
||||
void *BLI_lfmempool_iterstep(BLI_lfmempool_iter *iter);
|
||||
// int BLI_lfmempool_len(BLI_lfmempool *pool);
|
||||
void *BLI_lfmempool_iterstep_threaded(BLI_lfmempool *iter);
|
||||
void *BLI_lfmempool_findelem(BLI_lfmempool *pool, int index);
|
||||
|
||||
typedef struct ParallelLFMempoolTaskData {
|
||||
BLI_lfmempool_iter ts_iter;
|
||||
TaskParallelTLS tls;
|
||||
} ParallelLFMempoolTaskData;
|
||||
|
||||
ParallelLFMempoolTaskData *lfmempool_iter_threadsafe_create(BLI_lfmempool *pool,
|
||||
const size_t num_iter);
|
||||
void lfmempool_iter_threadsafe_destroy(ParallelLFMempoolTaskData *iter_arr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
|
|
|
@ -34,6 +34,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct BLI_mempool;
|
||||
struct BLI_lfmempool;
|
||||
|
||||
/* Task Scheduler
|
||||
*
|
||||
|
@ -236,6 +237,10 @@ void BLI_task_parallel_mempool(struct BLI_mempool *mempool,
|
|||
void *userdata,
|
||||
TaskParallelMempoolFunc func,
|
||||
const TaskParallelSettings *settings);
|
||||
void BLI_task_parallel_lfmempool(struct BLI_lfmempool *mempool,
|
||||
void *userdata,
|
||||
TaskParallelMempoolFunc func,
|
||||
const TaskParallelSettings *settings);
|
||||
|
||||
/* TODO(sergey): Think of a better place for this. */
|
||||
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
|
||||
|
|
|
@ -2,11 +2,17 @@
|
|||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_compiler_compat.h"
|
||||
|
||||
#include "atomic_ops.h" //for one atomic variable exposed to C, curchunk_threaded_shared in BLI_lfmempool_iter
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_mempool_lockfree.h"
|
||||
|
||||
/* NOTE: copied from BLO_blend_defs.h, don't use here because we're in BLI. */
|
||||
#ifdef __BIG_ENDIAN__
|
||||
/* Big Endian */
|
||||
|
@ -37,8 +43,6 @@
|
|||
*/
|
||||
#define USEDWORD MAKE_ID('u', 's', 'e', 'd')
|
||||
|
||||
typedef struct BLI_lfmempool BLI_lfmempool;
|
||||
|
||||
namespace blender {
|
||||
|
||||
struct LockFreeElem {
|
||||
|
@ -84,36 +88,50 @@ struct LockFreePool {
|
|||
|
||||
int esize, psize, csize;
|
||||
|
||||
LockFreePool(int esize, int psize) : esize(esize), psize(psize)
|
||||
LockFreePool(int _esize, int psize) : psize(psize)
|
||||
{
|
||||
esize = std::max(esize, (int)(sizeof(void *) * 2));
|
||||
esize = std::max(_esize, (int)(sizeof(void *) * 2));
|
||||
|
||||
if (esize & 8) {
|
||||
esize += 8 - (esize & 7);
|
||||
}
|
||||
|
||||
csize = esize * psize + sizeof(LockFreeChunk);
|
||||
totused.store(0);
|
||||
|
||||
free_elem.store(nullptr);
|
||||
chunks.first.store(nullptr);
|
||||
chunks.last.store(nullptr);
|
||||
}
|
||||
|
||||
~LockFreePool()
|
||||
{
|
||||
LockFreeChunk *chunk, *next;
|
||||
|
||||
for (chunk = chunks.first; chunk; chunk = next) {
|
||||
next = chunk->next;
|
||||
for (chunk = chunks.last; chunk; chunk = next) {
|
||||
next = chunk->prev;
|
||||
|
||||
OBJECT_GUARDED_DELETE(chunk, LockFreeChunk);
|
||||
MEM_freeN(reinterpret_cast<void *>(chunk));
|
||||
}
|
||||
}
|
||||
|
||||
void add_chunk()
|
||||
{
|
||||
LockFreeChunk *chunk = OBJECT_GUARDED_NEW(LockFreeChunk);
|
||||
LockFreeChunk *chunk = reinterpret_cast<LockFreeChunk *>(MEM_mallocN(csize, "LockFreeChunk"));
|
||||
LockFreeElem *elem = elem_from_chunk(chunk), *last;
|
||||
LockFreeElem *first = elem;
|
||||
|
||||
chunk->next = chunk->prev = nullptr;
|
||||
|
||||
for (int i = 0; i < psize; i++, elem = elem_next(elem, esize)) {
|
||||
elem->next = i == psize - 1 ? nullptr : elem_next(elem, esize);
|
||||
elem->freeword = FREEWORD;
|
||||
|
||||
if (i == psize - 1) {
|
||||
last = elem;
|
||||
elem->next = nullptr;
|
||||
}
|
||||
else {
|
||||
elem->next = elem_next(elem, esize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,7 +141,7 @@ struct LockFreePool {
|
|||
while (1) {
|
||||
last->next = free_elem.load();
|
||||
|
||||
if (free_elem.compare_exchange_strong(last->next, last)) {
|
||||
if (free_elem.compare_exchange_strong(last->next, first)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -137,6 +155,9 @@ struct LockFreePool {
|
|||
// is destroyed
|
||||
chunks.first.store(chunk);
|
||||
}
|
||||
else {
|
||||
chunk->prev->next = chunk;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -144,6 +165,8 @@ struct LockFreePool {
|
|||
|
||||
void *alloc()
|
||||
{
|
||||
totused++;
|
||||
|
||||
while (1) {
|
||||
if (!free_elem.load()) {
|
||||
add_chunk();
|
||||
|
@ -160,6 +183,7 @@ struct LockFreePool {
|
|||
|
||||
void free(void *mem)
|
||||
{
|
||||
totused--;
|
||||
LockFreeElem *elem = reinterpret_cast<LockFreeElem *>(mem);
|
||||
|
||||
elem->freeword = FREEWORD;
|
||||
|
@ -182,12 +206,6 @@ BLI_lfmempool *BLI_lfmempool_create(int esize, int psize)
|
|||
return reinterpret_cast<BLI_lfmempool *>(pool);
|
||||
}
|
||||
|
||||
typedef struct BLI_lfmempool_iter {
|
||||
void *chunk;
|
||||
BLI_lfmempool *pool;
|
||||
int i;
|
||||
} BLI_lfmempool_iter;
|
||||
|
||||
void BLI_lfmempool_destroy(BLI_lfmempool *pool)
|
||||
{
|
||||
OBJECT_GUARDED_DELETE(cast_pool(pool), LockFreePool);
|
||||
|
@ -198,6 +216,16 @@ void *BLI_lfmempool_alloc(BLI_lfmempool *pool)
|
|||
return cast_pool(pool)->alloc();
|
||||
}
|
||||
|
||||
void *BLI_lfmempool_calloc(BLI_lfmempool *_pool)
|
||||
{
|
||||
void *mem = BLI_lfmempool_alloc(_pool);
|
||||
LockFreePool *pool = cast_pool(_pool);
|
||||
|
||||
memset(mem, 0, pool->esize);
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
void BLI_lfmempool_free(BLI_lfmempool *pool, void *mem)
|
||||
{
|
||||
return cast_pool(pool)->free(mem);
|
||||
|
@ -209,6 +237,49 @@ void BLI_lfmempool_iternew(BLI_lfmempool *_pool, BLI_lfmempool_iter *iter)
|
|||
iter->pool = _pool;
|
||||
iter->chunk = reinterpret_cast<void *>(pool->chunks.first.load());
|
||||
iter->i = 0;
|
||||
iter->curchunk_threaded_shared = nullptr;
|
||||
}
|
||||
|
||||
static void *chunk_next(void *vchunk)
|
||||
{
|
||||
LockFreeChunk *chunk = reinterpret_cast<LockFreeChunk *>(vchunk);
|
||||
|
||||
return reinterpret_cast<void *>(chunk->next);
|
||||
}
|
||||
|
||||
void *BLI_lfmempool_iterstep_threadsafe(BLI_lfmempool_iter *iter)
|
||||
{
|
||||
if (!iter->chunk) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
LockFreePool *pool = cast_pool(iter->pool);
|
||||
LockFreeChunk *chunk = reinterpret_cast<LockFreeChunk *>(iter->chunk);
|
||||
|
||||
char *data = reinterpret_cast<char *>(data_from_chunk(chunk));
|
||||
void *ret = reinterpret_cast<void *>(data + pool->esize * iter->i);
|
||||
|
||||
iter->i++;
|
||||
|
||||
if (iter->i >= pool->psize) {
|
||||
iter->i = 0;
|
||||
/* Begin unique to the `threadsafe` version of this function. */
|
||||
for (iter->chunk = *iter->curchunk_threaded_shared;
|
||||
(iter->chunk != NULL) && (atomic_cas_ptr((void **)iter->curchunk_threaded_shared,
|
||||
iter->chunk,
|
||||
chunk_next(iter->chunk)) != iter->chunk);
|
||||
iter->chunk = *iter->curchunk_threaded_shared) {
|
||||
/* pass. */
|
||||
}
|
||||
iter->chunk = reinterpret_cast<void *>(chunk->next);
|
||||
}
|
||||
|
||||
LockFreeElem *elem = reinterpret_cast<LockFreeElem *>(ret);
|
||||
if (elem->freeword == FREEWORD) {
|
||||
return BLI_lfmempool_iterstep_threadsafe(iter);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *BLI_lfmempool_iterstep(BLI_lfmempool_iter *iter)
|
||||
|
@ -237,5 +308,67 @@ void *BLI_lfmempool_iterstep(BLI_lfmempool_iter *iter)
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *BLI_lfmempool_findelem(BLI_lfmempool *pool, int index)
|
||||
{
|
||||
BLI_lfmempool_iter iter;
|
||||
BLI_lfmempool_iternew(pool, &iter);
|
||||
void *item = BLI_lfmempool_iterstep(&iter);
|
||||
|
||||
int i = 0;
|
||||
|
||||
for (; item; item = BLI_lfmempool_iterstep(&iter), i++) {
|
||||
if (i == index) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize an array of mempool iterators, #BLI_MEMPOOL_ALLOW_ITER flag must be set.
|
||||
*
|
||||
* This is used in threaded code, to generate as much iterators as needed
|
||||
* (each task should have its own),
|
||||
* such that each iterator goes over its own single chunk,
|
||||
* and only getting the next chunk to iterate over has to be
|
||||
* protected against concurrency (which can be done in a lockless way).
|
||||
*
|
||||
* To be used when creating a task for each single item in the pool is totally overkill.
|
||||
*
|
||||
* See BLI_task_parallel_mempool implementation for detailed usage example.
|
||||
*/
|
||||
ParallelLFMempoolTaskData *lfmempool_iter_threadsafe_create(BLI_lfmempool *pool,
|
||||
const size_t num_iter)
|
||||
{
|
||||
BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
|
||||
|
||||
ParallelLFMempoolTaskData *iter_arr = (ParallelLFMempoolTaskData *)MEM_mallocN(
|
||||
sizeof(*iter_arr) * num_iter, __func__);
|
||||
LockFreeChunk **curchunk_threaded_shared = (LockFreeChunk **)MEM_mallocN(sizeof(void *),
|
||||
__func__);
|
||||
|
||||
BLI_lfmempool_iternew(pool, &iter_arr->ts_iter);
|
||||
|
||||
*curchunk_threaded_shared = reinterpret_cast<LockFreeChunk *>(iter_arr->ts_iter.chunk);
|
||||
iter_arr->ts_iter.curchunk_threaded_shared = reinterpret_cast<void **>(curchunk_threaded_shared);
|
||||
for (size_t i = 1; i < num_iter; i++) {
|
||||
iter_arr[i].ts_iter = iter_arr[0].ts_iter;
|
||||
*curchunk_threaded_shared = ((*curchunk_threaded_shared) ? (*curchunk_threaded_shared)->next :
|
||||
NULL);
|
||||
iter_arr[i].ts_iter.chunk = reinterpret_cast<void *>(*curchunk_threaded_shared);
|
||||
}
|
||||
|
||||
return iter_arr;
|
||||
}
|
||||
|
||||
void lfmempool_iter_threadsafe_destroy(ParallelLFMempoolTaskData *iter_arr)
|
||||
{
|
||||
BLI_assert(iter_arr->ts_iter.curchunk_threaded_shared != NULL);
|
||||
|
||||
MEM_freeN(iter_arr->ts_iter.curchunk_threaded_shared);
|
||||
MEM_freeN(iter_arr);
|
||||
}
|
||||
}
|
||||
} // namespace blender
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "BLI_listbase.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_mempool.h"
|
||||
#include "BLI_mempool_lockfree.h"
|
||||
#include "BLI_mempool_private.h"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_threads.h"
|
||||
|
@ -388,6 +389,18 @@ static void parallel_mempool_func(TaskPool *__restrict pool, void *taskdata)
|
|||
}
|
||||
}
|
||||
|
||||
static void parallel_lfmempool_func(TaskPool *__restrict pool, void *taskdata)
|
||||
{
|
||||
ParallelMempoolState *__restrict state = BLI_task_pool_user_data(pool);
|
||||
BLI_lfmempool_iter *iter = &((ParallelLFMempoolTaskData *)taskdata)->ts_iter;
|
||||
TaskParallelTLS *tls = &((ParallelLFMempoolTaskData *)taskdata)->tls;
|
||||
|
||||
MempoolIterData *item;
|
||||
while ((item = BLI_lfmempool_iterstep(iter)) != NULL) {
|
||||
state->func(state->userdata, item, tls);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This function allows to parallelize for loops over Mempool items.
|
||||
*
|
||||
|
@ -495,6 +508,109 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool,
|
|||
mempool_iter_threadsafe_destroy(mempool_iterator_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function allows to parallelize for loops over Mempool items.
|
||||
*
|
||||
* \param mempool: The iterable BLI_mempool to loop over.
|
||||
* \param userdata: Common userdata passed to all instances of \a func.
|
||||
* \param func: Callback function.
|
||||
* \param settings: See public API doc of TaskParallelSettings for description of all settings.
|
||||
*
|
||||
* \note There is no static scheduling here.
|
||||
*/
|
||||
void BLI_task_parallel_lfmempool(BLI_lfmempool *mempool,
|
||||
void *userdata,
|
||||
TaskParallelMempoolFunc func,
|
||||
const TaskParallelSettings *settings)
|
||||
{
|
||||
void *userdata_chunk = settings->userdata_chunk;
|
||||
const size_t userdata_chunk_size = settings->userdata_chunk_size;
|
||||
void *userdata_chunk_array = NULL;
|
||||
const bool use_userdata_chunk = (userdata_chunk_size != 0) && (userdata_chunk != NULL);
|
||||
|
||||
if (!settings->use_threading) {
|
||||
TaskParallelTLS tls = {NULL};
|
||||
if (use_userdata_chunk) {
|
||||
if (settings->func_init != NULL) {
|
||||
settings->func_init(userdata, userdata_chunk);
|
||||
}
|
||||
tls.userdata_chunk = userdata_chunk;
|
||||
}
|
||||
|
||||
BLI_lfmempool_iter iter;
|
||||
BLI_lfmempool_iternew(mempool, &iter);
|
||||
|
||||
void *item;
|
||||
while ((item = BLI_lfmempool_iterstep(&iter))) {
|
||||
func(userdata, item, &tls);
|
||||
}
|
||||
|
||||
if (use_userdata_chunk) {
|
||||
if (settings->func_free != NULL) {
|
||||
/* `func_free` should only free data that was created during execution of `func`. */
|
||||
settings->func_free(userdata, userdata_chunk);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ParallelMempoolState state;
|
||||
TaskPool *task_pool = BLI_task_pool_create(&state, TASK_PRIORITY_HIGH);
|
||||
const int num_threads = BLI_task_scheduler_num_threads();
|
||||
|
||||
/* The idea here is to prevent creating task for each of the loop iterations
|
||||
* and instead have tasks which are evenly distributed across CPU cores and
|
||||
* pull next item to be crunched using the threaded-aware BLI_mempool_iter.
|
||||
*/
|
||||
const int num_tasks = num_threads + 2;
|
||||
|
||||
state.userdata = userdata;
|
||||
state.func = func;
|
||||
|
||||
if (use_userdata_chunk) {
|
||||
userdata_chunk_array = MALLOCA(userdata_chunk_size * num_tasks);
|
||||
}
|
||||
|
||||
ParallelLFMempoolTaskData *mempool_iterator_data = lfmempool_iter_threadsafe_create(
|
||||
mempool, (size_t)num_tasks);
|
||||
|
||||
for (int i = 0; i < num_tasks; i++) {
|
||||
void *userdata_chunk_local = NULL;
|
||||
if (use_userdata_chunk) {
|
||||
userdata_chunk_local = (char *)userdata_chunk_array + (userdata_chunk_size * i);
|
||||
memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size);
|
||||
if (settings->func_init != NULL) {
|
||||
settings->func_init(userdata, userdata_chunk_local);
|
||||
}
|
||||
}
|
||||
mempool_iterator_data[i].tls.userdata_chunk = userdata_chunk_local;
|
||||
|
||||
/* Use this pool's pre-allocated tasks. */
|
||||
BLI_task_pool_push(task_pool, parallel_lfmempool_func, &mempool_iterator_data[i], false, NULL);
|
||||
}
|
||||
|
||||
BLI_task_pool_work_and_wait(task_pool);
|
||||
BLI_task_pool_free(task_pool);
|
||||
|
||||
if (use_userdata_chunk) {
|
||||
if ((settings->func_free != NULL) || (settings->func_reduce != NULL)) {
|
||||
for (int i = 0; i < num_tasks; i++) {
|
||||
if (settings->func_reduce) {
|
||||
settings->func_reduce(
|
||||
userdata, userdata_chunk, mempool_iterator_data[i].tls.userdata_chunk);
|
||||
}
|
||||
if (settings->func_free) {
|
||||
settings->func_free(userdata, mempool_iterator_data[i].tls.userdata_chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
MALLOCA_FREE(userdata_chunk_array, userdata_chunk_size * num_tasks);
|
||||
}
|
||||
|
||||
lfmempool_iter_threadsafe_destroy(mempool_iterator_data);
|
||||
}
|
||||
|
||||
#undef MALLOCA
|
||||
#undef MALLOCA_FREE
|
||||
|
||||
|
|
|
@ -34,6 +34,38 @@
|
|||
* these are ifdef'd because they use more memory and can't be saved in DNA currently */
|
||||
// #define USE_BMESH_HOLES
|
||||
|
||||
//#define BM_LOCKFREE_MEMPOOL
|
||||
#ifdef BM_LOCKFREE_MEMPOOL
|
||||
# include "BLI_mempool_lockfree.h"
|
||||
# include "BLI_threads.h"
|
||||
|
||||
# define BM_task_parallel_mempool BLI_task_parallel_lfmempool
|
||||
|
||||
# define BM_mempool BLI_lfmempool
|
||||
# define BM_mempool_create(esize, totelem, pchunk, flag) BLI_lfmempool_create(esize, pchunk)
|
||||
# define BM_mempool_alloc(pool) BLI_lfmempool_alloc(pool)
|
||||
# define BM_mempool_calloc(pool) BLI_lfmempool_calloc(pool)
|
||||
# define BM_mempool_destroy(pool) BLI_lfmempool_destroy((BLI_lfmempool *)pool)
|
||||
# define BM_mempool_iter BLI_lfmempool_iter
|
||||
# define BM_mempool_iternew(pool, iter) BLI_lfmempool_iternew(pool, iter)
|
||||
# define BM_mempool_iterstep(iter) BLI_lfmempool_iterstep(iter)
|
||||
# define BM_mempool_free(pool, elem) BLI_lfmempool_free(pool, elem)
|
||||
# define BM_mempool_findelem(pool, elem) BLI_lfmempool_findelem(pool, elem)
|
||||
#else
|
||||
# define BM_task_parallel_mempool BLI_task_parallel_mempool
|
||||
# define BM_mempool BLI_mempool
|
||||
# define BM_mempool_create(esize, totelem, pchunk, flag) \
|
||||
BLI_mempool_create(esize, totelem, pchunk, flag)
|
||||
# define BM_mempool_alloc(pool) BLI_mempool_alloc(pool)
|
||||
# define BM_mempool_calloc(pool) BLI_mempool_calloc(pool)
|
||||
# define BM_mempool_destroy(pool) BLI_mempool_destroy(pool)
|
||||
# define BM_mempool_iter BLI_mempool_iter
|
||||
# define BM_mempool_iternew(pool, iter) BLI_mempool_iternew(pool, iter)
|
||||
# define BM_mempool_iterstep(iter) BLI_mempool_iterstep(iter)
|
||||
# define BM_mempool_free(pool, elem) BLI_mempool_free(pool, elem)
|
||||
# define BM_mempool_findelem(pool, elem) BLI_mempool_findelem(pool, elem)
|
||||
#endif
|
||||
|
||||
struct BMEdge;
|
||||
struct BMFace;
|
||||
struct BMLoop;
|
||||
|
@ -312,7 +344,7 @@ typedef struct BMesh {
|
|||
char elem_table_dirty;
|
||||
|
||||
/* element pools */
|
||||
struct BLI_mempool *vpool, *epool, *lpool, *fpool;
|
||||
struct BM_mempool *vpool, *epool, *lpool, *fpool;
|
||||
|
||||
/* mempool lookup tables (optional)
|
||||
* index tables, to map indices to elements via
|
||||
|
@ -329,7 +361,7 @@ typedef struct BMesh {
|
|||
int ftable_tot;
|
||||
|
||||
/* operator api stuff (must be all NULL or all alloc'd) */
|
||||
struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool;
|
||||
struct BM_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool;
|
||||
|
||||
uint use_toolflags : 1;
|
||||
|
||||
|
@ -395,7 +427,13 @@ typedef struct BMesh {
|
|||
struct GHash *ghash; // used if BM_NO_REUSE_IDS is true
|
||||
int map_size;
|
||||
int cd_id_off[15];
|
||||
|
||||
#ifdef BM_LOCKFREE_MEMPOOL
|
||||
// XXX locks!
|
||||
TicketMutex *lock;
|
||||
#endif
|
||||
} idmap;
|
||||
|
||||
} BMesh;
|
||||
|
||||
enum {
|
||||
|
|
|
@ -43,6 +43,14 @@
|
|||
|
||||
#define SELECT 1
|
||||
|
||||
#ifdef BM_LOCKFREE_MEMPOOL
|
||||
# define BM_ID_LOCK(bm) BLI_ticket_mutex_lock(bm->idmap.lock)
|
||||
# define BM_ID_UNLOCK(bm) BLI_ticket_mutex_unlock(bm->idmap.lock)
|
||||
#else
|
||||
# define BM_ID_LOCK(bm)
|
||||
# define BM_ID_UNLOCK(bm)
|
||||
#endif
|
||||
|
||||
#ifdef WITH_BM_ID_FREELIST
|
||||
static uint bm_id_freelist_pop(BMesh *bm)
|
||||
{
|
||||
|
@ -165,6 +173,8 @@ void bm_assign_id_intern(BMesh *bm, BMElem *elem, uint id)
|
|||
|
||||
void bm_assign_id(BMesh *bm, BMElem *elem, uint id, bool check_unqiue)
|
||||
{
|
||||
BM_ID_LOCK(bm);
|
||||
|
||||
if (check_unqiue && (bm->idmap.flag & BM_HAS_ID_MAP)) {
|
||||
if (BM_ELEM_FROM_ID(bm, id)) {
|
||||
|
||||
|
@ -178,6 +188,8 @@ void bm_assign_id(BMesh *bm, BMElem *elem, uint id, bool check_unqiue)
|
|||
range_tree_uint_retake(bm->idmap.idtree, id);
|
||||
#endif
|
||||
bm_assign_id_intern(bm, elem, id);
|
||||
|
||||
BM_ID_UNLOCK(bm);
|
||||
}
|
||||
|
||||
void bm_alloc_id(BMesh *bm, BMElem *elem)
|
||||
|
@ -186,6 +198,8 @@ void bm_alloc_id(BMesh *bm, BMElem *elem)
|
|||
return;
|
||||
}
|
||||
|
||||
BM_ID_LOCK(bm);
|
||||
|
||||
#ifdef WITH_BM_ID_FREELIST
|
||||
uint id;
|
||||
|
||||
|
@ -200,6 +214,7 @@ void bm_alloc_id(BMesh *bm, BMElem *elem)
|
|||
#endif
|
||||
|
||||
bm_assign_id_intern(bm, elem, id);
|
||||
BM_ID_UNLOCK(bm);
|
||||
}
|
||||
|
||||
void bm_free_id(BMesh *bm, BMElem *elem)
|
||||
|
@ -208,6 +223,8 @@ void bm_free_id(BMesh *bm, BMElem *elem)
|
|||
return;
|
||||
}
|
||||
|
||||
BM_ID_LOCK(bm);
|
||||
|
||||
uint id = (uint)BM_ELEM_CD_GET_INT(elem, bm->idmap.cd_id_off[elem->head.htype]);
|
||||
|
||||
#ifndef WITH_BM_ID_FREELIST
|
||||
|
@ -227,6 +244,8 @@ void bm_free_id(BMesh *bm, BMElem *elem)
|
|||
BLI_ghash_remove(bm->idmap.ghash, POINTER_FROM_UINT(id), NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
BM_ID_UNLOCK(bm);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1288,11 +1307,11 @@ void bm_rebuild_idmap(BMesh *bm)
|
|||
cd_off = CustomData_get_offset(cdatas[i], CD_MESH_ID);
|
||||
|
||||
if (bm->idmap.flag & BM_NO_REUSE_IDS) {
|
||||
BLI_mempool_iter iter;
|
||||
BM_mempool_iter iter;
|
||||
|
||||
BLI_mempool_iternew((&bm->vpool)[i], &iter);
|
||||
BMElem *elem = (BMElem *)BLI_mempool_iterstep(&iter);
|
||||
for (; elem; elem = (BMElem *)BLI_mempool_iterstep(&iter)) {
|
||||
BM_mempool_iternew((&bm->vpool)[i], &iter);
|
||||
BMElem *elem = (BMElem *)BM_mempool_iterstep(&iter);
|
||||
for (; elem; elem = (BMElem *)BM_mempool_iterstep(&iter)) {
|
||||
void **val;
|
||||
|
||||
if (!BLI_ghash_ensure_p(bm->idmap.ghash, (void *)elem, &val)) {
|
||||
|
@ -1301,11 +1320,11 @@ void bm_rebuild_idmap(BMesh *bm)
|
|||
}
|
||||
}
|
||||
else {
|
||||
BLI_mempool_iter iter;
|
||||
BM_mempool_iter iter;
|
||||
|
||||
BLI_mempool_iternew((&bm->vpool)[i], &iter);
|
||||
BMElem *elem = (BMElem *)BLI_mempool_iterstep(&iter);
|
||||
for (; elem; elem = (BMElem *)BLI_mempool_iterstep(&iter)) {
|
||||
BM_mempool_iternew((&bm->vpool)[i], &iter);
|
||||
BMElem *elem = (BMElem *)BM_mempool_iterstep(&iter);
|
||||
for (; elem; elem = (BMElem *)BM_mempool_iterstep(&iter)) {
|
||||
void **val;
|
||||
int id = BM_ELEM_CD_GET_INT(elem, cd_off);
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ void bm_elem_check_toolflags(BMesh *bm, BMElem *elem)
|
|||
{
|
||||
int cd_off = -1;
|
||||
MToolFlags *flags;
|
||||
BLI_mempool *flagpool;
|
||||
BM_mempool *flagpool;
|
||||
|
||||
switch (elem->head.htype) {
|
||||
case BM_VERT:
|
||||
|
@ -87,7 +87,7 @@ void bm_elem_check_toolflags(BMesh *bm, BMElem *elem)
|
|||
|
||||
flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(elem, cd_off);
|
||||
if (!flags->flag) {
|
||||
flags->flag = BLI_mempool_calloc(flagpool);
|
||||
flags->flag = BM_mempool_calloc(flagpool);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ BMVert *BM_vert_create(BMesh *bm,
|
|||
const BMVert *v_example,
|
||||
const eBMCreateFlag create_flag)
|
||||
{
|
||||
BMVert *v = BLI_mempool_alloc(bm->vpool);
|
||||
BMVert *v = BM_mempool_alloc(bm->vpool);
|
||||
|
||||
BLI_assert((v_example == NULL) || (v_example->head.htype == BM_VERT));
|
||||
BLI_assert(!(create_flag & 1));
|
||||
|
@ -174,7 +174,7 @@ BMVert *BM_vert_create(BMesh *bm,
|
|||
if (bm->use_toolflags && v->head.data) {
|
||||
int cd_tflags = bm->vdata.layers[bm->vdata.typemap[CD_TOOLFLAGS]].offset;
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(v, cd_tflags);
|
||||
flags->flag = BLI_mempool_calloc(bm->vtoolflagpool);
|
||||
flags->flag = BM_mempool_calloc(bm->vtoolflagpool);
|
||||
}
|
||||
|
||||
BM_CHECK_ELEMENT(v);
|
||||
|
@ -203,7 +203,7 @@ BMEdge *BM_edge_create(
|
|||
return e;
|
||||
}
|
||||
|
||||
e = BLI_mempool_alloc(bm->epool);
|
||||
e = BM_mempool_alloc(bm->epool);
|
||||
|
||||
/* --- assign all members --- */
|
||||
e->head.data = NULL;
|
||||
|
@ -252,7 +252,7 @@ BMEdge *BM_edge_create(
|
|||
if (bm->use_toolflags && e->head.data) {
|
||||
int cd_tflags = bm->edata.layers[bm->edata.typemap[CD_TOOLFLAGS]].offset;
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(e, cd_tflags);
|
||||
flags->flag = BLI_mempool_calloc(bm->etoolflagpool);
|
||||
flags->flag = BM_mempool_calloc(bm->etoolflagpool);
|
||||
}
|
||||
|
||||
BM_CHECK_ELEMENT(e);
|
||||
|
@ -274,7 +274,7 @@ static BMLoop *bm_loop_create(BMesh *bm,
|
|||
{
|
||||
BMLoop *l = NULL;
|
||||
|
||||
l = BLI_mempool_alloc(bm->lpool);
|
||||
l = BM_mempool_alloc(bm->lpool);
|
||||
|
||||
BLI_assert((l_example == NULL) || (l_example->head.htype == BM_LOOP));
|
||||
BLI_assert(!(create_flag & 1));
|
||||
|
@ -339,7 +339,7 @@ static BMLoop *bm_face_boundary_add(
|
|||
BMesh *bm, BMFace *f, BMVert *startv, BMEdge *starte, const eBMCreateFlag create_flag)
|
||||
{
|
||||
#ifdef USE_BMESH_HOLES
|
||||
BMLoopList *lst = BLI_mempool_calloc(bm->looplistpool);
|
||||
BMLoopList *lst = BM_mempool_calloc(bm->looplistpool);
|
||||
#endif
|
||||
BMLoop *l = bm_loop_create(bm, startv, starte, f, NULL /* starte->l */, create_flag);
|
||||
|
||||
|
@ -432,7 +432,7 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm)
|
|||
{
|
||||
BMFace *f;
|
||||
|
||||
f = BLI_mempool_alloc(bm->fpool);
|
||||
f = BM_mempool_alloc(bm->fpool);
|
||||
|
||||
/* --- assign all members --- */
|
||||
f->head.data = NULL;
|
||||
|
@ -552,7 +552,7 @@ BMFace *BM_face_create(BMesh *bm,
|
|||
if (bm->use_toolflags && f->head.data) {
|
||||
int cd_tflags = bm->pdata.layers[bm->pdata.typemap[CD_TOOLFLAGS]].offset;
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(f, cd_tflags);
|
||||
flags->flag = BLI_mempool_calloc(bm->ftoolflagpool);
|
||||
flags->flag = BM_mempool_calloc(bm->ftoolflagpool);
|
||||
}
|
||||
|
||||
BM_CHECK_ELEMENT(f);
|
||||
|
@ -833,7 +833,7 @@ static void bm_kill_only_vert(BMesh *bm, BMVert *v)
|
|||
MToolFlags *flags = BM_ELEM_CD_GET_VOID_P(
|
||||
v, bm->vdata.layers[bm->vdata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
BLI_mempool_free(bm->vtoolflagpool, flags->flag);
|
||||
BM_mempool_free(bm->vtoolflagpool, flags->flag);
|
||||
flags->flag = NULL;
|
||||
|
||||
if (bleh) {
|
||||
|
@ -845,7 +845,7 @@ static void bm_kill_only_vert(BMesh *bm, BMVert *v)
|
|||
CustomData_bmesh_free_block(&bm->vdata, &v->head.data);
|
||||
}
|
||||
|
||||
BLI_mempool_free(bm->vpool, v);
|
||||
BM_mempool_free(bm->vpool, v);
|
||||
}
|
||||
|
||||
#ifdef WITH_BM_ID_FREELIST
|
||||
|
@ -943,14 +943,14 @@ void bm_kill_only_edge(BMesh *bm, BMEdge *e)
|
|||
MToolFlags *flags = BM_ELEM_CD_GET_VOID_P(
|
||||
e, bm->edata.layers[bm->edata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
BLI_mempool_free(bm->etoolflagpool, flags->flag);
|
||||
BM_mempool_free(bm->etoolflagpool, flags->flag);
|
||||
}
|
||||
|
||||
if (e->head.data) {
|
||||
CustomData_bmesh_free_block(&bm->edata, &e->head.data);
|
||||
}
|
||||
|
||||
BLI_mempool_free(bm->epool, e);
|
||||
BM_mempool_free(bm->epool, e);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -976,14 +976,14 @@ void bm_kill_only_face(BMesh *bm, BMFace *f)
|
|||
MToolFlags *flags = BM_ELEM_CD_GET_VOID_P(
|
||||
f, bm->pdata.layers[bm->pdata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
BLI_mempool_free(bm->ftoolflagpool, flags->flag);
|
||||
BM_mempool_free(bm->ftoolflagpool, flags->flag);
|
||||
}
|
||||
|
||||
if (f->head.data) {
|
||||
CustomData_bmesh_free_block(&bm->pdata, &f->head.data);
|
||||
}
|
||||
|
||||
BLI_mempool_free(bm->fpool, f);
|
||||
BM_mempool_free(bm->fpool, f);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1002,7 +1002,7 @@ void bm_kill_only_loop(BMesh *bm, BMLoop *l)
|
|||
CustomData_bmesh_free_block(&bm->ldata, &l->head.data);
|
||||
}
|
||||
|
||||
BLI_mempool_free(bm->lpool, l);
|
||||
BM_mempool_free(bm->lpool, l);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1087,7 +1087,7 @@ void BM_face_kill(BMesh *bm, BMFace *f)
|
|||
} while ((l_iter = l_next) != l_first);
|
||||
|
||||
#ifdef USE_BMESH_HOLES
|
||||
BLI_mempool_free(bm->looplistpool, ls);
|
||||
BM_mempool_free(bm->looplistpool, ls);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1146,7 +1146,7 @@ void BM_face_kill_loose(BMesh *bm, BMFace *f)
|
|||
} while ((l_iter = l_next) != l_first);
|
||||
|
||||
#ifdef USE_BMESH_HOLES
|
||||
BLI_mempool_free(bm->looplistpool, ls);
|
||||
BM_mempool_free(bm->looplistpool, ls);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1581,7 +1581,7 @@ static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *f_example)
|
|||
f = bm_face_create__internal(bm);
|
||||
|
||||
#ifdef USE_BMESH_HOLES
|
||||
lst = BLI_mempool_calloc(bm->looplistpool);
|
||||
lst = BM_mempool_calloc(bm->looplistpool);
|
||||
BLI_addtail(&f->loops, lst);
|
||||
#endif
|
||||
|
||||
|
@ -1595,7 +1595,7 @@ static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *f_example)
|
|||
if (bm->use_toolflags && f->head.data) {
|
||||
int cd_tflags = bm->pdata.layers[bm->pdata.typemap[CD_TOOLFLAGS]].offset;
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(f, cd_tflags);
|
||||
flags->flag = BLI_mempool_calloc(bm->ftoolflagpool);
|
||||
flags->flag = BM_mempool_calloc(bm->ftoolflagpool);
|
||||
}
|
||||
|
||||
return f;
|
||||
|
@ -1766,7 +1766,7 @@ BMFace *bmesh_kernel_split_face_make_edge(BMesh *bm,
|
|||
// printf("warning: call to split face euler without holes argument; holes will be tossed.\n");
|
||||
for (lst = f->loops.last; lst != f->loops.first; lst = lst2) {
|
||||
lst2 = lst->prev;
|
||||
BLI_mempool_free(bm->looplistpool, lst);
|
||||
BM_mempool_free(bm->looplistpool, lst);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -2512,7 +2512,8 @@ static void trigger_jvke_error(int err, char *obj_text)
|
|||
printf("========= ERROR %s============\n\n%s\n\n", get_err_str(err), obj_text);
|
||||
}
|
||||
|
||||
#if 0
|
||||
//#define JVKE_DEBUG
|
||||
#ifdef JVKE_DEBUG
|
||||
# define JVKE_CHECK_ELEMENT(elem) \
|
||||
{ \
|
||||
int err = 0; \
|
||||
|
@ -2529,9 +2530,11 @@ BMVert *bmesh_kernel_join_vert_kill_edge(
|
|||
{
|
||||
BMVert *v_conn = BM_edge_other_vert(e, v_kill);
|
||||
|
||||
#ifdef JVKE_DEBUG
|
||||
char buf[LOCAL_OBJ_SIZE];
|
||||
char *saved_obj = bm_save_local_obj_text(bm, 2, buf, "e", e);
|
||||
bm_local_obj_free(saved_obj, buf);
|
||||
#endif
|
||||
|
||||
BMFace **fs = NULL;
|
||||
BMEdge **deles = NULL;
|
||||
|
@ -3012,23 +3015,23 @@ BMFace *bmesh_kernel_join_face_kill_edge(BMesh *bm, BMFace *f1, BMFace *f2, BMEd
|
|||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(
|
||||
l_f1->e, bm->edata.layers[bm->edata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
BLI_mempool_free(bm->etoolflagpool, flags->flag);
|
||||
BM_mempool_free(bm->etoolflagpool, flags->flag);
|
||||
}
|
||||
BLI_mempool_free(bm->epool, l_f1->e);
|
||||
BM_mempool_free(bm->epool, l_f1->e);
|
||||
bm->totedge--;
|
||||
BLI_mempool_free(bm->lpool, l_f1);
|
||||
BM_mempool_free(bm->lpool, l_f1);
|
||||
bm->totloop--;
|
||||
BLI_mempool_free(bm->lpool, l_f2);
|
||||
BM_mempool_free(bm->lpool, l_f2);
|
||||
bm->totloop--;
|
||||
|
||||
if (bm->ftoolflagpool) {
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(
|
||||
f2, bm->pdata.layers[bm->pdata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
BLI_mempool_free(bm->ftoolflagpool, flags->flag);
|
||||
BM_mempool_free(bm->ftoolflagpool, flags->flag);
|
||||
}
|
||||
|
||||
BLI_mempool_free(bm->fpool, f2);
|
||||
BM_mempool_free(bm->fpool, f2);
|
||||
bm->totface--;
|
||||
/* account for both above */
|
||||
bm->elem_index_dirty |= BM_EDGE | BM_LOOP | BM_FACE;
|
||||
|
|
|
@ -1292,7 +1292,7 @@ void BM_vert_interp_from_face(BMesh *bm, BMVert *v_dst, const BMFace *f_src)
|
|||
static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
|
||||
{
|
||||
BMIter iter;
|
||||
BLI_mempool *oldpool = olddata->pool;
|
||||
BM_mempool *oldpool = (BM_mempool *)olddata->pool;
|
||||
void *block;
|
||||
|
||||
CustomDataLayer **nocopy_layers = NULL;
|
||||
|
@ -1376,7 +1376,7 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
|
|||
/* this should never happen but can when dissolve fails - T28960. */
|
||||
BLI_assert(data->pool != oldpool);
|
||||
|
||||
BLI_mempool_destroy(oldpool);
|
||||
BM_mempool_destroy((BM_mempool *)oldpool);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -421,17 +421,17 @@ int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const
|
|||
void bmiter__elem_of_mesh_begin(struct BMIter__elem_of_mesh *iter)
|
||||
{
|
||||
#ifdef USE_IMMUTABLE_ASSERT
|
||||
((BMIter *)iter)->count = BLI_mempool_len(iter->pooliter.pool);
|
||||
((BMIter *)iter)->count = BM_mempool_len(iter->pooliter.pool);
|
||||
#endif
|
||||
BLI_mempool_iternew(iter->pooliter.pool, &iter->pooliter);
|
||||
BM_mempool_iternew(iter->pooliter.pool, &iter->pooliter);
|
||||
}
|
||||
|
||||
void *bmiter__elem_of_mesh_step(struct BMIter__elem_of_mesh *iter)
|
||||
{
|
||||
#ifdef USE_IMMUTABLE_ASSERT
|
||||
BLI_assert(((BMIter *)iter)->count <= BLI_mempool_len(iter->pooliter.pool));
|
||||
BLI_assert(((BMIter *)iter)->count <= BM_mempool_len(iter->pooliter.pool));
|
||||
#endif
|
||||
return BLI_mempool_iterstep(&iter->pooliter);
|
||||
return BM_mempool_iterstep(&iter->pooliter);
|
||||
}
|
||||
|
||||
#ifdef USE_IMMUTABLE_ASSERT
|
||||
|
|
|
@ -110,7 +110,7 @@ extern const char bm_iter_itype_htype_map[BM_ITYPE_MAX];
|
|||
|
||||
/* iterator type structs */
|
||||
struct BMIter__elem_of_mesh {
|
||||
BLI_mempool_iter pooliter;
|
||||
BM_mempool_iter pooliter;
|
||||
};
|
||||
struct BMIter__edge_of_vert {
|
||||
BMVert *vdata;
|
||||
|
|
|
@ -192,13 +192,13 @@ BLI_INLINE void BM_iter_parallel(BMesh *bm,
|
|||
/* inlining optimizes out this switch when called with the defined type */
|
||||
switch ((BMIterType)itype) {
|
||||
case BM_VERTS_OF_MESH:
|
||||
BLI_task_parallel_mempool(bm->vpool, userdata, func, settings);
|
||||
BM_task_parallel_mempool(bm->vpool, userdata, func, settings);
|
||||
break;
|
||||
case BM_EDGES_OF_MESH:
|
||||
BLI_task_parallel_mempool(bm->epool, userdata, func, settings);
|
||||
BM_task_parallel_mempool(bm->epool, userdata, func, settings);
|
||||
break;
|
||||
case BM_FACES_OF_MESH:
|
||||
BLI_task_parallel_mempool(bm->fpool, userdata, func, settings);
|
||||
BM_task_parallel_mempool(bm->fpool, userdata, func, settings);
|
||||
break;
|
||||
default:
|
||||
/* should never happen */
|
||||
|
|
|
@ -689,7 +689,7 @@ static void bm_log_vert_customdata(
|
|||
|
||||
if (lv->customdata) {
|
||||
CustomData_bmesh_asan_unpoison(&entry->vdata, lv->customdata);
|
||||
BLI_mempool_free(entry->vdata.pool, lv->customdata);
|
||||
BM_mempool_free((BM_mempool *)entry->vdata.pool, lv->customdata);
|
||||
lv->customdata = NULL;
|
||||
}
|
||||
|
||||
|
@ -706,7 +706,7 @@ static void bm_log_edge_customdata(
|
|||
{
|
||||
if (le->customdata) {
|
||||
CustomData_bmesh_asan_unpoison(&entry->edata, le->customdata);
|
||||
BLI_mempool_free(entry->edata.pool, le->customdata);
|
||||
BM_mempool_free((BM_mempool *)entry->edata.pool, le->customdata);
|
||||
le->customdata = NULL;
|
||||
}
|
||||
|
||||
|
@ -724,7 +724,7 @@ static void bm_log_face_customdata(BMesh *bm, BMLog *log, BMFace *f, BMLogFace *
|
|||
|
||||
if (lf->customdata_f) {
|
||||
CustomData_bmesh_asan_unpoison(&entry->pdata, lf->customdata_f);
|
||||
BLI_mempool_free(entry->pdata.pool, lf->customdata_f);
|
||||
BM_mempool_free((BM_mempool *)entry->pdata.pool, lf->customdata_f);
|
||||
lf->customdata_f = NULL;
|
||||
}
|
||||
|
||||
|
@ -738,7 +738,7 @@ static void bm_log_face_customdata(BMesh *bm, BMLog *log, BMFace *f, BMLogFace *
|
|||
do {
|
||||
if (lf->customdata[i]) {
|
||||
CustomData_bmesh_asan_unpoison(&entry->ldata, lf->customdata[i]);
|
||||
BLI_mempool_free(entry->ldata.pool, lf->customdata[i]);
|
||||
BM_mempool_free((BM_mempool *)entry->ldata.pool, lf->customdata[i]);
|
||||
lf->customdata[i] = NULL;
|
||||
}
|
||||
|
||||
|
@ -910,14 +910,14 @@ static void bm_log_face_bmface_copy(
|
|||
|
||||
if (lf->customdata_f) {
|
||||
CustomData_bmesh_asan_unpoison(&entry->pdata, lf->customdata_f);
|
||||
BLI_mempool_free(entry->pdata.pool, lf->customdata_f);
|
||||
BM_mempool_free((BM_mempool *)entry->pdata.pool, lf->customdata_f);
|
||||
lf->customdata_f = NULL;
|
||||
}
|
||||
|
||||
for (uint i = 0; i < lf->len; i++) {
|
||||
if (lf->customdata[i]) {
|
||||
CustomData_bmesh_asan_unpoison(&entry->ldata, lf->customdata[i]);
|
||||
BLI_mempool_free(entry->ldata.pool, lf->customdata[i]);
|
||||
BM_mempool_free((BM_mempool *)entry->ldata.pool, lf->customdata[i]);
|
||||
lf->customdata[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -1413,7 +1413,7 @@ static void bm_log_faces_restore(
|
|||
static void bm_log_vert_values_swap(
|
||||
BMesh *bm, BMLog *log, GHash *verts, BMLogEntry *entry, BMLogCallbacks *callbacks)
|
||||
{
|
||||
void *scratch = bm->vdata.pool ? BLI_mempool_alloc(bm->vdata.pool) : NULL;
|
||||
void *scratch = bm->vdata.pool ? BM_mempool_alloc((BM_mempool *)bm->vdata.pool) : NULL;
|
||||
|
||||
GHashIterator gh_iter;
|
||||
GHASH_ITER (gh_iter, verts) {
|
||||
|
@ -1462,14 +1462,14 @@ static void bm_log_vert_values_swap(
|
|||
}
|
||||
|
||||
if (scratch) {
|
||||
BLI_mempool_free(bm->vdata.pool, scratch);
|
||||
BM_mempool_free((BM_mempool *)bm->vdata.pool, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
static void bm_log_edge_values_swap(
|
||||
BMesh *bm, BMLog *log, GHash *edges, BMLogEntry *entry, BMLogCallbacks *callbacks)
|
||||
{
|
||||
void *scratch = bm->edata.pool ? BLI_mempool_alloc(bm->edata.pool) : NULL;
|
||||
void *scratch = bm->edata.pool ? BM_mempool_alloc((BM_mempool *)bm->edata.pool) : NULL;
|
||||
|
||||
GHashIterator gh_iter;
|
||||
GHASH_ITER (gh_iter, edges) {
|
||||
|
@ -1497,7 +1497,7 @@ static void bm_log_edge_values_swap(
|
|||
}
|
||||
|
||||
if (scratch) {
|
||||
BLI_mempool_free(bm->edata.pool, scratch);
|
||||
BM_mempool_free((BM_mempool *)bm->edata.pool, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1506,7 +1506,7 @@ static void bm_log_face_values_swap(BMLog *log,
|
|||
BMLogEntry *entry,
|
||||
BMLogCallbacks *callbacks)
|
||||
{
|
||||
void *scratch = log->bm->pdata.pool ? BLI_mempool_alloc(log->bm->pdata.pool) : NULL;
|
||||
void *scratch = log->bm->pdata.pool ? BM_mempool_alloc((BM_mempool *)log->bm->pdata.pool) : NULL;
|
||||
|
||||
GHashIterator gh_iter;
|
||||
GHASH_ITER (gh_iter, faces) {
|
||||
|
@ -1545,7 +1545,7 @@ static void bm_log_face_values_swap(BMLog *log,
|
|||
}
|
||||
|
||||
if (scratch) {
|
||||
BLI_mempool_free(log->bm->pdata.pool, scratch);
|
||||
BM_mempool_free((BM_mempool *)log->bm->pdata.pool, scratch);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1657,11 +1657,11 @@ static void bm_log_entry_free_direct(BMLogEntry *entry)
|
|||
int cd_mdisps = CustomData_get_offset(&entry->ldata, CD_MDISPS);
|
||||
|
||||
/* iterate over cdata blocks directly */
|
||||
BLI_mempool_iter iter;
|
||||
BLI_mempool_iternew(entry->ldata.pool, &iter);
|
||||
void *block = BLI_mempool_iterstep(&iter);
|
||||
BM_mempool_iter iter;
|
||||
BM_mempool_iternew((BM_mempool *)entry->ldata.pool, &iter);
|
||||
void *block = BM_mempool_iterstep(&iter);
|
||||
|
||||
for (; block; block = BLI_mempool_iterstep(&iter)) {
|
||||
for (; block; block = BM_mempool_iterstep(&iter)) {
|
||||
BMElem elem;
|
||||
elem.head.data = block;
|
||||
|
||||
|
@ -1673,16 +1673,16 @@ static void bm_log_entry_free_direct(BMLogEntry *entry)
|
|||
}
|
||||
|
||||
if (entry->vdata.pool) {
|
||||
BLI_mempool_destroy(entry->vdata.pool);
|
||||
BM_mempool_destroy(entry->vdata.pool);
|
||||
}
|
||||
if (entry->edata.pool) {
|
||||
BLI_mempool_destroy(entry->edata.pool);
|
||||
BM_mempool_destroy(entry->edata.pool);
|
||||
}
|
||||
if (entry->ldata.pool) {
|
||||
BLI_mempool_destroy(entry->ldata.pool);
|
||||
BM_mempool_destroy(entry->ldata.pool);
|
||||
}
|
||||
if (entry->pdata.pool) {
|
||||
BLI_mempool_destroy(entry->pdata.pool);
|
||||
BM_mempool_destroy(entry->pdata.pool);
|
||||
}
|
||||
|
||||
CustomData_free(&entry->vdata, 0);
|
||||
|
@ -3426,11 +3426,12 @@ static int bmlog_entry_memsize(BMLogEntry *entry)
|
|||
ret += (int)BLI_mempool_get_size(entry->pool_verts);
|
||||
ret += (int)BLI_mempool_get_size(entry->pool_edges);
|
||||
ret += (int)BLI_mempool_get_size(entry->pool_faces);
|
||||
#ifndef BM_LOCKFREE_MEMPOOL
|
||||
ret += entry->vdata.pool ? (int)BLI_mempool_get_size(entry->vdata.pool) : 0;
|
||||
ret += entry->edata.pool ? (int)BLI_mempool_get_size(entry->edata.pool) : 0;
|
||||
ret += entry->ldata.pool ? (int)BLI_mempool_get_size(entry->ldata.pool) : 0;
|
||||
ret += entry->pdata.pool ? (int)BLI_mempool_get_size(entry->pdata.pool) : 0;
|
||||
|
||||
#endif
|
||||
ret += BLI_memarena_size(entry->arena);
|
||||
|
||||
if (BLI_memarena_size(entry->arena)) {
|
||||
|
|
|
@ -49,10 +49,10 @@ static void bm_alloc_toolflags(BMesh *bm);
|
|||
|
||||
static void bm_mempool_init_ex(const BMAllocTemplate *allocsize,
|
||||
const bool use_toolflags,
|
||||
BLI_mempool **r_vpool,
|
||||
BLI_mempool **r_epool,
|
||||
BLI_mempool **r_lpool,
|
||||
BLI_mempool **r_fpool)
|
||||
BM_mempool **r_vpool,
|
||||
BM_mempool **r_epool,
|
||||
BM_mempool **r_lpool,
|
||||
BM_mempool **r_fpool)
|
||||
{
|
||||
size_t vert_size, edge_size, loop_size, face_size;
|
||||
|
||||
|
@ -70,19 +70,19 @@ static void bm_mempool_init_ex(const BMAllocTemplate *allocsize,
|
|||
}
|
||||
|
||||
if (r_vpool) {
|
||||
*r_vpool = BLI_mempool_create(
|
||||
*r_vpool = BM_mempool_create(
|
||||
vert_size, allocsize->totvert, bm_mesh_chunksize_default.totvert, BLI_MEMPOOL_ALLOW_ITER);
|
||||
}
|
||||
if (r_epool) {
|
||||
*r_epool = BLI_mempool_create(
|
||||
*r_epool = BM_mempool_create(
|
||||
edge_size, allocsize->totedge, bm_mesh_chunksize_default.totedge, BLI_MEMPOOL_ALLOW_ITER);
|
||||
}
|
||||
if (r_lpool) {
|
||||
*r_lpool = BLI_mempool_create(
|
||||
*r_lpool = BM_mempool_create(
|
||||
loop_size, allocsize->totloop, bm_mesh_chunksize_default.totloop, BLI_MEMPOOL_ALLOW_ITER);
|
||||
}
|
||||
if (r_fpool) {
|
||||
*r_fpool = BLI_mempool_create(
|
||||
*r_fpool = BM_mempool_create(
|
||||
face_size, allocsize->totface, bm_mesh_chunksize_default.totface, BLI_MEMPOOL_ALLOW_ITER);
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize, const b
|
|||
bm_mempool_init_ex(allocsize, use_toolflags, &bm->vpool, &bm->epool, &bm->lpool, &bm->fpool);
|
||||
|
||||
#ifdef USE_BMESH_HOLES
|
||||
bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), 512, 512, BLI_MEMPOOL_NOP);
|
||||
bm->looplistpool = BM_mempool_create(sizeof(BMLoopList), 512, 512, BLI_MEMPOOL_NOP);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -104,9 +104,9 @@ void BM_mesh_elem_toolflags_ensure(BMesh *bm)
|
|||
return;
|
||||
}
|
||||
|
||||
bm->vtoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), bm->totvert, 512, BLI_MEMPOOL_NOP);
|
||||
bm->etoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), bm->totedge, 512, BLI_MEMPOOL_NOP);
|
||||
bm->ftoolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), bm->totface, 512, BLI_MEMPOOL_NOP);
|
||||
bm->vtoolflagpool = BM_mempool_create(sizeof(BMFlagLayer), bm->totvert, 512, BLI_MEMPOOL_NOP);
|
||||
bm->etoolflagpool = BM_mempool_create(sizeof(BMFlagLayer), bm->totedge, 512, BLI_MEMPOOL_NOP);
|
||||
bm->ftoolflagpool = BM_mempool_create(sizeof(BMFlagLayer), bm->totface, 512, BLI_MEMPOOL_NOP);
|
||||
|
||||
bm_alloc_toolflags(bm);
|
||||
|
||||
|
@ -118,15 +118,15 @@ void BM_mesh_elem_toolflags_clear(BMesh *bm)
|
|||
bool haveflags = bm->vtoolflagpool || bm->etoolflagpool || bm->ftoolflagpool;
|
||||
|
||||
if (bm->vtoolflagpool) {
|
||||
BLI_mempool_destroy(bm->vtoolflagpool);
|
||||
BM_mempool_destroy(bm->vtoolflagpool);
|
||||
bm->vtoolflagpool = NULL;
|
||||
}
|
||||
if (bm->etoolflagpool) {
|
||||
BLI_mempool_destroy(bm->etoolflagpool);
|
||||
BM_mempool_destroy(bm->etoolflagpool);
|
||||
bm->etoolflagpool = NULL;
|
||||
}
|
||||
if (bm->ftoolflagpool) {
|
||||
BLI_mempool_destroy(bm->ftoolflagpool);
|
||||
BM_mempool_destroy(bm->ftoolflagpool);
|
||||
bm->ftoolflagpool = NULL;
|
||||
}
|
||||
|
||||
|
@ -168,6 +168,10 @@ BMesh *BM_mesh_create(const BMAllocTemplate *allocsize, const struct BMeshCreate
|
|||
/* allocate the structure */
|
||||
BMesh *bm = MEM_callocN(sizeof(BMesh), __func__);
|
||||
|
||||
#ifdef BM_LOCKFREE_MEMPOOL
|
||||
bm->idmap.lock = BLI_ticket_mutex_alloc();
|
||||
#endif
|
||||
|
||||
/* allocate the memory pools for the mesh elements */
|
||||
bm_mempool_init(bm, allocsize, params->use_toolflags);
|
||||
|
||||
|
@ -314,16 +318,16 @@ void BM_mesh_data_free(BMesh *bm)
|
|||
|
||||
/* Free custom data pools, This should probably go in CustomData_free? */
|
||||
if (bm->vdata.totlayer) {
|
||||
BLI_mempool_destroy(bm->vdata.pool);
|
||||
BM_mempool_destroy(bm->vdata.pool);
|
||||
}
|
||||
if (bm->edata.totlayer) {
|
||||
BLI_mempool_destroy(bm->edata.pool);
|
||||
BM_mempool_destroy(bm->edata.pool);
|
||||
}
|
||||
if (bm->ldata.totlayer) {
|
||||
BLI_mempool_destroy(bm->ldata.pool);
|
||||
BM_mempool_destroy(bm->ldata.pool);
|
||||
}
|
||||
if (bm->pdata.totlayer) {
|
||||
BLI_mempool_destroy(bm->pdata.pool);
|
||||
BM_mempool_destroy(bm->pdata.pool);
|
||||
}
|
||||
|
||||
/* free custom data */
|
||||
|
@ -333,10 +337,10 @@ void BM_mesh_data_free(BMesh *bm)
|
|||
CustomData_free(&bm->pdata, 0);
|
||||
|
||||
/* destroy element pools */
|
||||
BLI_mempool_destroy(bm->vpool);
|
||||
BLI_mempool_destroy(bm->epool);
|
||||
BLI_mempool_destroy(bm->lpool);
|
||||
BLI_mempool_destroy(bm->fpool);
|
||||
BM_mempool_destroy(bm->vpool);
|
||||
BM_mempool_destroy(bm->epool);
|
||||
BM_mempool_destroy(bm->lpool);
|
||||
BM_mempool_destroy(bm->fpool);
|
||||
|
||||
if (bm->vtable) {
|
||||
MEM_freeN(bm->vtable);
|
||||
|
@ -351,20 +355,20 @@ void BM_mesh_data_free(BMesh *bm)
|
|||
/* destroy flag pools */
|
||||
|
||||
if (bm->vtoolflagpool) {
|
||||
BLI_mempool_destroy(bm->vtoolflagpool);
|
||||
BM_mempool_destroy(bm->vtoolflagpool);
|
||||
bm->vtoolflagpool = NULL;
|
||||
}
|
||||
if (bm->etoolflagpool) {
|
||||
BLI_mempool_destroy(bm->etoolflagpool);
|
||||
BM_mempool_destroy(bm->etoolflagpool);
|
||||
bm->etoolflagpool = NULL;
|
||||
}
|
||||
if (bm->ftoolflagpool) {
|
||||
BLI_mempool_destroy(bm->ftoolflagpool);
|
||||
BM_mempool_destroy(bm->ftoolflagpool);
|
||||
bm->ftoolflagpool = NULL;
|
||||
}
|
||||
|
||||
#ifdef USE_BMESH_HOLES
|
||||
BLI_mempool_destroy(bm->looplistpool);
|
||||
BM_mempool_destroy(bm->looplistpool);
|
||||
#endif
|
||||
|
||||
BLI_freelistN(&bm->selected);
|
||||
|
@ -838,17 +842,17 @@ void BM_mesh_elem_table_free(BMesh *bm, const char htype)
|
|||
|
||||
BMVert *BM_vert_at_index_find(BMesh *bm, const int index)
|
||||
{
|
||||
return BLI_mempool_findelem(bm->vpool, index);
|
||||
return BM_mempool_findelem(bm->vpool, index);
|
||||
}
|
||||
|
||||
BMEdge *BM_edge_at_index_find(BMesh *bm, const int index)
|
||||
{
|
||||
return BLI_mempool_findelem(bm->epool, index);
|
||||
return BM_mempool_findelem(bm->epool, index);
|
||||
}
|
||||
|
||||
BMFace *BM_face_at_index_find(BMesh *bm, const int index)
|
||||
{
|
||||
return BLI_mempool_findelem(bm->fpool, index);
|
||||
return BM_mempool_findelem(bm->fpool, index);
|
||||
}
|
||||
|
||||
BMLoop *BM_loop_at_index_find(BMesh *bm, const int index)
|
||||
|
@ -1036,12 +1040,12 @@ void BM_mesh_remap(BMesh *bm,
|
|||
BMLoop **ltable = MEM_malloc_arrayN(bm->totloop, sizeof(*ltable), "ltable");
|
||||
|
||||
BMLoop *ed;
|
||||
BLI_mempool_iter liter;
|
||||
BLI_mempool_iternew(bm->lpool, &liter);
|
||||
BMLoop *l = (BMLoop *)BLI_mempool_iterstep(&liter);
|
||||
BM_mempool_iter liter;
|
||||
BM_mempool_iternew(bm->lpool, &liter);
|
||||
BMLoop *l = (BMLoop *)BM_mempool_iterstep(&liter);
|
||||
|
||||
int i = 0;
|
||||
for (; l; l = (BMLoop *)BLI_mempool_iterstep(&liter), i++) {
|
||||
for (; l; l = (BMLoop *)BM_mempool_iterstep(&liter), i++) {
|
||||
l->head.index = i;
|
||||
ltable[i] = l;
|
||||
}
|
||||
|
@ -1412,10 +1416,10 @@ void BM_mesh_remap(BMesh *bm,
|
|||
*/
|
||||
void BM_mesh_rebuild(BMesh *bm,
|
||||
const struct BMeshCreateParams *params,
|
||||
BLI_mempool *vpool_dst,
|
||||
BLI_mempool *epool_dst,
|
||||
BLI_mempool *lpool_dst,
|
||||
BLI_mempool *fpool_dst)
|
||||
BM_mempool *vpool_dst,
|
||||
BM_mempool *epool_dst,
|
||||
BM_mempool *lpool_dst,
|
||||
BM_mempool *fpool_dst)
|
||||
{
|
||||
const char remap = (vpool_dst ? BM_VERT : 0) | (epool_dst ? BM_EDGE : 0) |
|
||||
(lpool_dst ? BM_LOOP : 0) | (fpool_dst ? BM_FACE : 0);
|
||||
|
@ -1436,13 +1440,13 @@ void BM_mesh_rebuild(BMesh *bm,
|
|||
int index;
|
||||
BMVert *v_src;
|
||||
BM_ITER_MESH_INDEX (v_src, &iter, bm, BM_VERTS_OF_MESH, index) {
|
||||
BMVert *v_dst = BLI_mempool_alloc(vpool_dst);
|
||||
BMVert *v_dst = BM_mempool_alloc(vpool_dst);
|
||||
memcpy(v_dst, v_src, sizeof(BMVert));
|
||||
if (use_toolflags) {
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(
|
||||
v_dst, bm->vdata.layers[bm->vdata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
flags->flag = bm->vtoolflagpool ? BLI_mempool_calloc(bm->vtoolflagpool) : NULL;
|
||||
flags->flag = bm->vtoolflagpool ? BM_mempool_calloc(bm->vtoolflagpool) : NULL;
|
||||
}
|
||||
|
||||
vtable_dst[index] = v_dst;
|
||||
|
@ -1455,13 +1459,13 @@ void BM_mesh_rebuild(BMesh *bm,
|
|||
int index;
|
||||
BMEdge *e_src;
|
||||
BM_ITER_MESH_INDEX (e_src, &iter, bm, BM_EDGES_OF_MESH, index) {
|
||||
BMEdge *e_dst = BLI_mempool_alloc(epool_dst);
|
||||
BMEdge *e_dst = BM_mempool_alloc(epool_dst);
|
||||
memcpy(e_dst, e_src, sizeof(BMEdge));
|
||||
if (use_toolflags) {
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(
|
||||
e_dst, bm->edata.layers[bm->edata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
flags->flag = bm->etoolflagpool ? BLI_mempool_calloc(bm->etoolflagpool) : NULL;
|
||||
flags->flag = bm->etoolflagpool ? BM_mempool_calloc(bm->etoolflagpool) : NULL;
|
||||
}
|
||||
|
||||
etable_dst[index] = e_dst;
|
||||
|
@ -1476,14 +1480,14 @@ void BM_mesh_rebuild(BMesh *bm,
|
|||
BM_ITER_MESH_INDEX (f_src, &iter, bm, BM_FACES_OF_MESH, index) {
|
||||
|
||||
if (remap & BM_FACE) {
|
||||
BMFace *f_dst = BLI_mempool_alloc(fpool_dst);
|
||||
BMFace *f_dst = BM_mempool_alloc(fpool_dst);
|
||||
memcpy(f_dst, f_src, sizeof(BMFace));
|
||||
|
||||
if (use_toolflags) {
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(
|
||||
f_dst, bm->pdata.layers[bm->pdata.typemap[CD_TOOLFLAGS]].offset);
|
||||
|
||||
flags->flag = bm->ftoolflagpool ? BLI_mempool_calloc(bm->ftoolflagpool) : NULL;
|
||||
flags->flag = bm->ftoolflagpool ? BM_mempool_calloc(bm->ftoolflagpool) : NULL;
|
||||
}
|
||||
|
||||
ftable_dst[index] = f_dst;
|
||||
|
@ -1495,7 +1499,7 @@ void BM_mesh_rebuild(BMesh *bm,
|
|||
BMLoop *l_iter_src, *l_first_src;
|
||||
l_iter_src = l_first_src = BM_FACE_FIRST_LOOP((BMFace *)f_src);
|
||||
do {
|
||||
BMLoop *l_dst = BLI_mempool_alloc(lpool_dst);
|
||||
BMLoop *l_dst = BM_mempool_alloc(lpool_dst);
|
||||
memcpy(l_dst, l_iter_src, sizeof(BMLoop));
|
||||
ltable_dst[index_loop] = l_dst;
|
||||
BM_elem_index_set(l_iter_src, index_loop++); /* set_ok */
|
||||
|
@ -1631,7 +1635,7 @@ void BM_mesh_rebuild(BMesh *bm,
|
|||
bm->elem_table_dirty &= ~BM_VERT;
|
||||
}
|
||||
MEM_freeN(vtable_dst);
|
||||
BLI_mempool_destroy(bm->vpool);
|
||||
BM_mempool_destroy(bm->vpool);
|
||||
bm->vpool = vpool_dst;
|
||||
}
|
||||
|
||||
|
@ -1642,14 +1646,14 @@ void BM_mesh_rebuild(BMesh *bm,
|
|||
bm->elem_table_dirty &= ~BM_EDGE;
|
||||
}
|
||||
MEM_freeN(etable_dst);
|
||||
BLI_mempool_destroy(bm->epool);
|
||||
BM_mempool_destroy(bm->epool);
|
||||
bm->epool = epool_dst;
|
||||
}
|
||||
|
||||
if (remap & BM_LOOP) {
|
||||
/* no loop table */
|
||||
MEM_freeN(ltable_dst);
|
||||
BLI_mempool_destroy(bm->lpool);
|
||||
BM_mempool_destroy(bm->lpool);
|
||||
bm->lpool = lpool_dst;
|
||||
}
|
||||
|
||||
|
@ -1660,7 +1664,7 @@ void BM_mesh_rebuild(BMesh *bm,
|
|||
bm->elem_table_dirty &= ~BM_FACE;
|
||||
}
|
||||
MEM_freeN(ftable_dst);
|
||||
BLI_mempool_destroy(bm->fpool);
|
||||
BM_mempool_destroy(bm->fpool);
|
||||
bm->fpool = fpool_dst;
|
||||
}
|
||||
|
||||
|
@ -1708,21 +1712,21 @@ static void bm_alloc_toolflags(BMesh *bm)
|
|||
bm_alloc_toolflags_cdlayers(bm, true);
|
||||
|
||||
CustomData *cdatas[3] = {&bm->vdata, &bm->edata, &bm->pdata};
|
||||
BLI_mempool *flagpools[3] = {bm->vtoolflagpool, bm->etoolflagpool, bm->ftoolflagpool};
|
||||
BLI_mempool *elempools[3] = {bm->vpool, bm->epool, bm->fpool};
|
||||
BM_mempool *flagpools[3] = {bm->vtoolflagpool, bm->etoolflagpool, bm->ftoolflagpool};
|
||||
BM_mempool *elempools[3] = {bm->vpool, bm->epool, bm->fpool};
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
CustomData *cdata = cdatas[i];
|
||||
int cd_tflags = CustomData_get_offset(cdata, CD_TOOLFLAGS);
|
||||
|
||||
BLI_mempool_iter iter;
|
||||
BLI_mempool_iternew(elempools[i], &iter);
|
||||
BMElem *elem = (BMElem *)BLI_mempool_iterstep(&iter);
|
||||
BM_mempool_iter iter;
|
||||
BM_mempool_iternew(elempools[i], &iter);
|
||||
BMElem *elem = (BMElem *)BM_mempool_iterstep(&iter);
|
||||
|
||||
for (; elem; elem = (BMElem *)BLI_mempool_iterstep(&iter)) {
|
||||
for (; elem; elem = (BMElem *)BM_mempool_iterstep(&iter)) {
|
||||
MToolFlags *flags = (MToolFlags *)BM_ELEM_CD_GET_VOID_P(elem, cd_tflags);
|
||||
|
||||
flags->flag = BLI_mempool_calloc(flagpools[i]);
|
||||
flags->flag = BM_mempool_calloc(flagpools[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1737,9 +1741,9 @@ void BM_mesh_toolflags_set(BMesh *bm, bool use_toolflags)
|
|||
}
|
||||
|
||||
if (use_toolflags == false) {
|
||||
BLI_mempool_destroy(bm->vtoolflagpool);
|
||||
BLI_mempool_destroy(bm->etoolflagpool);
|
||||
BLI_mempool_destroy(bm->ftoolflagpool);
|
||||
BM_mempool_destroy(bm->vtoolflagpool);
|
||||
BM_mempool_destroy(bm->etoolflagpool);
|
||||
BM_mempool_destroy(bm->ftoolflagpool);
|
||||
|
||||
bm->vtoolflagpool = NULL;
|
||||
bm->etoolflagpool = NULL;
|
||||
|
@ -2050,14 +2054,15 @@ bool BM_defragment_vertex(BMesh *bm,
|
|||
void (*on_vert_swap)(BMVert *a, BMVert *b, void *userdata),
|
||||
void *userdata)
|
||||
{
|
||||
#if 0
|
||||
BMEdge *e = v->e;
|
||||
|
||||
#if 1
|
||||
# if 1
|
||||
int cd_vcol = CustomData_get_offset(&bm->vdata, CD_PROP_COLOR);
|
||||
|
||||
if (cd_vcol >= 0) {
|
||||
float *color = BM_ELEM_CD_GET_VOID_P(v, cd_vcol);
|
||||
int idx = BLI_mempool_find_real_index(bm->vpool, (void *)v);
|
||||
int idx = BM_mempool_find_real_index(bm->vpool, (void *)v);
|
||||
int size = BLI_mempool_get_size(bm->vpool);
|
||||
|
||||
float f = (float)idx / (float)size / 2.0f;
|
||||
|
@ -2065,7 +2070,7 @@ bool BM_defragment_vertex(BMesh *bm,
|
|||
color[0] = color[1] = color[2] = f;
|
||||
color[3] = 1.0f;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
// return false;
|
||||
|
||||
|
@ -2174,7 +2179,7 @@ bool BM_defragment_vertex(BMesh *bm,
|
|||
on_vert_swap(v2, elems[i], userdata);
|
||||
BM_swap_verts(bm, v2, elems[i]);
|
||||
|
||||
#if 0
|
||||
# if 0
|
||||
BMIter iter;
|
||||
BMEdge *et;
|
||||
int f = 0;
|
||||
|
@ -2186,7 +2191,7 @@ bool BM_defragment_vertex(BMesh *bm,
|
|||
BM_ITER_ELEM (et, &iter, v, BM_EDGES_OF_VERT) {
|
||||
printf("an 1edge %d\n", f++);
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
// BM_swap_verts(bm, v2, elems[i]);
|
||||
|
||||
|
@ -2198,7 +2203,7 @@ bool BM_defragment_vertex(BMesh *bm,
|
|||
break;
|
||||
}
|
||||
} while ((e = BM_DISK_EDGE_NEXT(e, v)) != v->e);
|
||||
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
/** \} */
|
||||
|
|
|
@ -116,10 +116,10 @@ void BM_mesh_remap(BMesh *bm,
|
|||
|
||||
void BM_mesh_rebuild(BMesh *bm,
|
||||
const struct BMeshCreateParams *params,
|
||||
struct BLI_mempool *vpool,
|
||||
struct BLI_mempool *epool,
|
||||
struct BLI_mempool *lpool,
|
||||
struct BLI_mempool *fpool);
|
||||
struct BM_mempool *vpool,
|
||||
struct BM_mempool *epool,
|
||||
struct BM_mempool *lpool,
|
||||
struct BM_mempool *fpool);
|
||||
|
||||
typedef struct BMAllocTemplate {
|
||||
int totvert, totedge, totloop, totface;
|
||||
|
|
|
@ -100,16 +100,16 @@
|
|||
static void bm_free_cd_pools(BMesh *bm)
|
||||
{
|
||||
if (bm->vdata.pool) {
|
||||
BLI_mempool_destroy(bm->vdata.pool);
|
||||
BM_mempool_destroy(bm->vdata.pool);
|
||||
}
|
||||
if (bm->edata.pool) {
|
||||
BLI_mempool_destroy(bm->edata.pool);
|
||||
BM_mempool_destroy(bm->edata.pool);
|
||||
}
|
||||
if (bm->ldata.pool) {
|
||||
BLI_mempool_destroy(bm->ldata.pool);
|
||||
BM_mempool_destroy(bm->ldata.pool);
|
||||
}
|
||||
if (bm->pdata.pool) {
|
||||
BLI_mempool_destroy(bm->pdata.pool);
|
||||
BM_mempool_destroy(bm->pdata.pool);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ static void bm_mark_temp_cdlayers(BMesh *bm)
|
|||
CustomDataLayer *cl = (srcdata)->layers, *cl2 = (destdata)->layers; \
|
||||
int size = 0; \
|
||||
if (!*block) { \
|
||||
*block = BLI_mempool_alloc((destdata)->pool); \
|
||||
*block = BM_mempool_alloc((destdata)->pool); \
|
||||
} \
|
||||
for (int j = 0; j < (srcdata)->totlayer; j++, cl++) { \
|
||||
if ((destdata)->typemap[cl->type] < 0) { \
|
||||
|
@ -280,9 +280,9 @@ void BM_enter_multires_space(Object *ob, BMesh *bm, int space)
|
|||
*/
|
||||
|
||||
void BM_mesh_bm_from_me(Object *ob,
|
||||
BMesh *bm,
|
||||
const Mesh *me,
|
||||
const struct BMeshFromMeshParams *params)
|
||||
BMesh *bm,
|
||||
const Mesh *me,
|
||||
const struct BMeshFromMeshParams *params)
|
||||
{
|
||||
const bool is_new = !(bm->totvert || (bm->vdata.totlayer || bm->edata.totlayer ||
|
||||
bm->pdata.totlayer || bm->ldata.totlayer));
|
||||
|
@ -480,11 +480,11 @@ void BM_mesh_bm_from_me(Object *ob,
|
|||
bm_alloc_toolflags_cdlayers(bm, !is_new);
|
||||
|
||||
if (!bm->vtoolflagpool) {
|
||||
bm->vtoolflagpool = BLI_mempool_create(
|
||||
bm->vtoolflagpool = BM_mempool_create(
|
||||
sizeof(BMFlagLayer), bm->totvert, 512, BLI_MEMPOOL_NOP);
|
||||
bm->etoolflagpool = BLI_mempool_create(
|
||||
bm->etoolflagpool = BM_mempool_create(
|
||||
sizeof(BMFlagLayer), bm->totedge, 512, BLI_MEMPOOL_NOP);
|
||||
bm->ftoolflagpool = BLI_mempool_create(
|
||||
bm->ftoolflagpool = BM_mempool_create(
|
||||
sizeof(BMFlagLayer), bm->totface, 512, BLI_MEMPOOL_NOP);
|
||||
|
||||
bm->totflags = 1;
|
||||
|
@ -838,7 +838,7 @@ void BM_mesh_bm_from_me(Object *ob,
|
|||
|
||||
memset(bm->idmap.free_ids, 0, bm->idmap.free_ids_size * sizeof(*bm->idmap.free_ids));
|
||||
|
||||
BLI_mempool_iter miter;
|
||||
BM_mempool_iter miter;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
int htype = 1 << i;
|
||||
|
||||
|
@ -846,11 +846,11 @@ void BM_mesh_bm_from_me(Object *ob,
|
|||
continue;
|
||||
}
|
||||
|
||||
BLI_mempool *pool = (&bm->vpool)[i];
|
||||
BLI_mempool_iternew(pool, &miter);
|
||||
BMElem *elem = (BMElem *)BLI_mempool_iterstep(&miter);
|
||||
BM_mempool *pool = (&bm->vpool)[i];
|
||||
BM_mempool_iternew(pool, &miter);
|
||||
BMElem *elem = (BMElem *)BM_mempool_iterstep(&miter);
|
||||
|
||||
for (; elem; elem = (BMElem *)BLI_mempool_iterstep(&miter)) {
|
||||
for (; elem; elem = (BMElem *)BM_mempool_iterstep(&miter)) {
|
||||
uint id = (uint)BM_ELEM_GET_ID(bm, elem);
|
||||
|
||||
BLI_BITMAP_SET(bm->idmap.free_ids, id, true);
|
||||
|
|
|
@ -318,6 +318,10 @@ BMesh *BM_mesh_bm_from_me_threaded(BMesh *bm,
|
|||
const Mesh *me,
|
||||
const struct BMeshFromMeshParams *params)
|
||||
{
|
||||
# ifdef BM_LOCKFREE_MEMPOOL
|
||||
BM_mesh_bm_from_me(ob, bm, me, params);
|
||||
return bm;
|
||||
# else
|
||||
if (!bm) {
|
||||
bm = MEM_callocN(sizeof(BMesh), "BM_mesh_bm_from_me_threaded bm");
|
||||
}
|
||||
|
@ -585,6 +589,7 @@ BMesh *BM_mesh_bm_from_me_threaded(BMesh *bm,
|
|||
bm->elem_table_dirty = BM_VERT | BM_EDGE | BM_FACE;
|
||||
|
||||
return bm;
|
||||
# endif
|
||||
}
|
||||
|
||||
static void bm_unmark_temp_cdlayers(BMesh *bm)
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "BLI_math.h"
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_mempool.h"
|
||||
#include "BLI_mempool_lockfree.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
|
@ -1260,13 +1261,13 @@ static void bmo_flag_layer_do(BMesh *bm,
|
|||
int htype,
|
||||
int totelem,
|
||||
int new_totflags,
|
||||
BLI_mempool **pool_ptr))
|
||||
BM_mempool **pool_ptr))
|
||||
{
|
||||
int iters[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH};
|
||||
int types[3] = {BM_VERT, BM_EDGE, BM_FACE};
|
||||
int tots[3] = {bm->totvert, bm->totedge, bm->totface};
|
||||
|
||||
BLI_mempool **pools[3] = {&bm->vtoolflagpool, &bm->etoolflagpool, &bm->ftoolflagpool};
|
||||
BM_mempool **pools[3] = {&bm->vtoolflagpool, &bm->etoolflagpool, &bm->ftoolflagpool};
|
||||
CustomData *cdatas[3] = {&bm->vdata, &bm->edata, &bm->pdata};
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
|
@ -1288,22 +1289,22 @@ static void bmo_flag_layer_alloc_do(BMesh *bm,
|
|||
int htype,
|
||||
int totelem,
|
||||
int new_totflags,
|
||||
BLI_mempool **pool_ptr)
|
||||
BM_mempool **pool_ptr)
|
||||
{
|
||||
BMIter iter;
|
||||
BMElem *elem;
|
||||
int i;
|
||||
|
||||
const size_t old_totflags_size = (bm->totflags * sizeof(BMFlagLayer));
|
||||
BLI_mempool *oldpool = *pool_ptr;
|
||||
BLI_mempool *newpool = BLI_mempool_create(
|
||||
BM_mempool *oldpool = *pool_ptr;
|
||||
BM_mempool *newpool = BM_mempool_create(
|
||||
sizeof(BMFlagLayer) * new_totflags, totelem, 512, BLI_MEMPOOL_NOP);
|
||||
|
||||
BM_ITER_MESH_INDEX (elem, &iter, bm, itertype, i) {
|
||||
MToolFlags *flags = BM_ELEM_CD_GET_VOID_P(elem, cd_tflags);
|
||||
|
||||
short *oldflags = flags->flag;
|
||||
flags->flag = BLI_mempool_calloc(newpool);
|
||||
flags->flag = BM_mempool_calloc(newpool);
|
||||
|
||||
memcpy(flags->flag, oldflags, old_totflags_size);
|
||||
BM_elem_index_set(elem, i); /* set_inline */
|
||||
|
@ -1311,7 +1312,7 @@ static void bmo_flag_layer_alloc_do(BMesh *bm,
|
|||
}
|
||||
|
||||
*pool_ptr = newpool;
|
||||
BLI_mempool_destroy(oldpool);
|
||||
BM_mempool_destroy(oldpool);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1346,7 +1347,7 @@ static void bmo_flag_layer_clear_do(BMesh *bm,
|
|||
int htype,
|
||||
int totelem,
|
||||
int totflag,
|
||||
BLI_mempool **pool_ptr)
|
||||
BM_mempool **pool_ptr)
|
||||
{
|
||||
BMIter iter;
|
||||
BMElem *elem;
|
||||
|
|
|
@ -746,7 +746,7 @@ static void sculpt_gesture_face_set_begin(bContext *C, SculptGestureContext *sgc
|
|||
SCULPT_undo_push_node(sgcontext->vc.obact, NULL, SCULPT_UNDO_FACE_SETS);
|
||||
}
|
||||
|
||||
static void (void *__restrict userdata,
|
||||
static void face_set_gesture_apply_task_cb(void *__restrict userdata,
|
||||
const int i,
|
||||
const TaskParallelTLS *__restrict UNUSED(tls))
|
||||
{
|
||||
|
|
|
@ -587,7 +587,9 @@ int SCULPT_dyntopo_get_templayer(SculptSession *ss, int type, const char *name)
|
|||
}
|
||||
|
||||
char dyntopop_faces_areas_layer_id[] = "__dyntopo_face_areas";
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
extern char *cdlayer_lock_attr_name;
|
||||
#endif
|
||||
|
||||
void SCULPT_dyntopo_node_layers_add(SculptSession *ss)
|
||||
{
|
||||
|
@ -605,11 +607,13 @@ void SCULPT_dyntopo_node_layers_add(SculptSession *ss)
|
|||
|
||||
ss->cd_vert_mask_offset = CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK);
|
||||
|
||||
#ifdef WITH_DYNTOPO_EDGE_LOCKS
|
||||
BMCustomLayerReq elayers[] = {CD_PROP_INT32,
|
||||
cdlayer_lock_attr_name,
|
||||
CD_FLAG_TEMPORARY | CD_FLAG_ELEM_NOCOPY | CD_FLAG_ELEM_NOINTERP};
|
||||
|
||||
BM_data_layers_ensure(ss->bm, &ss->bm->edata, elayers, 1);
|
||||
#endif
|
||||
|
||||
BMCustomLayerReq flayers[] = {
|
||||
{CD_PROP_INT32, dyntopop_node_idx_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY},
|
||||
|
|
|
@ -1536,9 +1536,9 @@ void SCULPT_smooth(Sculpt *sd,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef PROXY_ADVANCED
|
||||
nodes = nodes ? MEM_dupallocN(nodes) : NULL;
|
||||
|
||||
#ifdef PROXY_ADVANCED
|
||||
int datamask = PV_CO | PV_NEIGHBORS | PV_NO | PV_INDEX | PV_MASK;
|
||||
BKE_pbvh_ensure_proxyarrays(ss, ss->pbvh, nodes, totnode, datamask);
|
||||
|
||||
|
@ -1584,6 +1584,10 @@ void SCULPT_smooth(Sculpt *sd,
|
|||
BKE_pbvh_gather_proxyarray(ss->pbvh, nodes, totnode);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef PROXY_ADVANCED
|
||||
MEM_SAFE_FREE(nodes);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SCULPT_do_smooth_brush(
|
||||
|
|
Loading…
Reference in New Issue