bmesh: lazy initialize bmesh tool flag pool, has the advantage that modifiers that dont use bmesh operators can skip allocating it.
This commit is contained in:
@@ -133,7 +133,10 @@ typedef struct BMLoop {
|
|||||||
/* can cast BMFace/BMEdge/BMVert, but NOT BMLoop, since these don't have a flag layer */
|
/* can cast BMFace/BMEdge/BMVert, but NOT BMLoop, since these don't have a flag layer */
|
||||||
typedef struct BMElemF {
|
typedef struct BMElemF {
|
||||||
BMHeader head;
|
BMHeader head;
|
||||||
struct BMFlagLayer *oflags; /* keep after header, an array of flags, mostly used by the operator stack */
|
|
||||||
|
/* keep directly after header,
|
||||||
|
* optional array of flags, only used by the operator stack */
|
||||||
|
struct BMFlagLayer *oflags;
|
||||||
} BMElemF;
|
} BMElemF;
|
||||||
|
|
||||||
/* can cast anything to this, including BMLoop */
|
/* can cast anything to this, including BMLoop */
|
||||||
|
@@ -76,7 +76,9 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* allocate flag */
|
/* allocate flag */
|
||||||
v->oflags = BLI_mempool_calloc(bm->toolflagpool);
|
if (bm->toolflagpool) {
|
||||||
|
v->oflags = BLI_mempool_calloc(bm->toolflagpool);
|
||||||
|
}
|
||||||
|
|
||||||
CustomData_bmesh_set_default(&bm->vdata, &v->head.data);
|
CustomData_bmesh_set_default(&bm->vdata, &v->head.data);
|
||||||
|
|
||||||
@@ -125,7 +127,9 @@ BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example,
|
|||||||
e->head.htype = BM_EDGE;
|
e->head.htype = BM_EDGE;
|
||||||
|
|
||||||
/* allocate flag */
|
/* allocate flag */
|
||||||
e->oflags = BLI_mempool_calloc(bm->toolflagpool);
|
if (bm->toolflagpool) {
|
||||||
|
e->oflags = BLI_mempool_calloc(bm->toolflagpool);
|
||||||
|
}
|
||||||
|
|
||||||
e->v1 = v1;
|
e->v1 = v1;
|
||||||
e->v2 = v2;
|
e->v2 = v2;
|
||||||
@@ -278,7 +282,9 @@ BLI_INLINE BMFace *bm_face_create__internal(BMesh *bm)
|
|||||||
f->head.htype = BM_FACE;
|
f->head.htype = BM_FACE;
|
||||||
|
|
||||||
/* allocate flag */
|
/* allocate flag */
|
||||||
f->oflags = BLI_mempool_calloc(bm->toolflagpool);
|
if (bm->toolflagpool) {
|
||||||
|
f->oflags = BLI_mempool_calloc(bm->toolflagpool);
|
||||||
|
}
|
||||||
|
|
||||||
CustomData_bmesh_set_default(&bm->pdata, &f->head.data);
|
CustomData_bmesh_set_default(&bm->pdata, &f->head.data);
|
||||||
|
|
||||||
@@ -495,7 +501,9 @@ static void bm_kill_only_vert(BMesh *bm, BMVert *v)
|
|||||||
if (v->head.data)
|
if (v->head.data)
|
||||||
CustomData_bmesh_free_block(&bm->vdata, &v->head.data);
|
CustomData_bmesh_free_block(&bm->vdata, &v->head.data);
|
||||||
|
|
||||||
BLI_mempool_free(bm->toolflagpool, v->oflags);
|
if (bm->toolflagpool) {
|
||||||
|
BLI_mempool_free(bm->toolflagpool, v->oflags);
|
||||||
|
}
|
||||||
BLI_mempool_free(bm->vpool, v);
|
BLI_mempool_free(bm->vpool, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -513,7 +521,9 @@ static void bm_kill_only_edge(BMesh *bm, BMEdge *e)
|
|||||||
if (e->head.data)
|
if (e->head.data)
|
||||||
CustomData_bmesh_free_block(&bm->edata, &e->head.data);
|
CustomData_bmesh_free_block(&bm->edata, &e->head.data);
|
||||||
|
|
||||||
BLI_mempool_free(bm->toolflagpool, e->oflags);
|
if (bm->toolflagpool) {
|
||||||
|
BLI_mempool_free(bm->toolflagpool, e->oflags);
|
||||||
|
}
|
||||||
BLI_mempool_free(bm->epool, e);
|
BLI_mempool_free(bm->epool, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -534,7 +544,9 @@ static void bm_kill_only_face(BMesh *bm, BMFace *f)
|
|||||||
if (f->head.data)
|
if (f->head.data)
|
||||||
CustomData_bmesh_free_block(&bm->pdata, &f->head.data);
|
CustomData_bmesh_free_block(&bm->pdata, &f->head.data);
|
||||||
|
|
||||||
BLI_mempool_free(bm->toolflagpool, f->oflags);
|
if (bm->toolflagpool) {
|
||||||
|
BLI_mempool_free(bm->toolflagpool, f->oflags);
|
||||||
|
}
|
||||||
BLI_mempool_free(bm->fpool, f);
|
BLI_mempool_free(bm->fpool, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1773,14 +1785,18 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e)
|
|||||||
bmesh_disk_edge_remove(f1loop->e, f1loop->e->v2);
|
bmesh_disk_edge_remove(f1loop->e, f1loop->e->v2);
|
||||||
|
|
||||||
/* deallocate edge and its two loops as well as f2 */
|
/* deallocate edge and its two loops as well as f2 */
|
||||||
BLI_mempool_free(bm->toolflagpool, f1loop->e->oflags);
|
if (bm->toolflagpool) {
|
||||||
|
BLI_mempool_free(bm->toolflagpool, f1loop->e->oflags);
|
||||||
|
}
|
||||||
BLI_mempool_free(bm->epool, f1loop->e);
|
BLI_mempool_free(bm->epool, f1loop->e);
|
||||||
bm->totedge--;
|
bm->totedge--;
|
||||||
BLI_mempool_free(bm->lpool, f1loop);
|
BLI_mempool_free(bm->lpool, f1loop);
|
||||||
bm->totloop--;
|
bm->totloop--;
|
||||||
BLI_mempool_free(bm->lpool, f2loop);
|
BLI_mempool_free(bm->lpool, f2loop);
|
||||||
bm->totloop--;
|
bm->totloop--;
|
||||||
BLI_mempool_free(bm->toolflagpool, f2->oflags);
|
if (bm->toolflagpool) {
|
||||||
|
BLI_mempool_free(bm->toolflagpool, f2->oflags);
|
||||||
|
}
|
||||||
BLI_mempool_free(bm->fpool, f2);
|
BLI_mempool_free(bm->fpool, f2);
|
||||||
bm->totface--;
|
bm->totface--;
|
||||||
/* account for both above */
|
/* account for both above */
|
||||||
|
@@ -59,9 +59,37 @@ static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize)
|
|||||||
#ifdef USE_BMESH_HOLES
|
#ifdef USE_BMESH_HOLES
|
||||||
bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), 512, 512, 0);
|
bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), 512, 512, 0);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* allocate one flag pool that we don't get rid of. */
|
void BM_mesh_elem_toolflags_ensure(BMesh *bm)
|
||||||
bm->toolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), 512, 512, 0);
|
{
|
||||||
|
if (bm->toolflagpool == NULL) {
|
||||||
|
const int totflagpool_size = max_ii(512, bm->totvert + bm->totedge + bm->totface);
|
||||||
|
BLI_mempool *toolflagpool;
|
||||||
|
|
||||||
|
BMIter iter;
|
||||||
|
BMElemF *ele;
|
||||||
|
const char iter_types[3] = {BM_VERTS_OF_MESH,
|
||||||
|
BM_EDGES_OF_MESH,
|
||||||
|
BM_FACES_OF_MESH};
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
BLI_assert(bm->totflags == 0);
|
||||||
|
|
||||||
|
/* allocate one flag pool that we don't get rid of. */
|
||||||
|
toolflagpool = BLI_mempool_create(sizeof(BMFlagLayer), totflagpool_size, 512, 0);
|
||||||
|
|
||||||
|
|
||||||
|
for (i = 0; i < 3; i++) {
|
||||||
|
BM_ITER_MESH (ele, &iter, bm, iter_types[i]) {
|
||||||
|
ele->oflags = BLI_mempool_calloc(toolflagpool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bm->toolflagpool = toolflagpool;
|
||||||
|
bm->totflags = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,7 +111,7 @@ BMesh *BM_mesh_create(BMAllocTemplate *allocsize)
|
|||||||
|
|
||||||
/* allocate one flag pool that we don't get rid of. */
|
/* allocate one flag pool that we don't get rid of. */
|
||||||
bm->stackdepth = 1;
|
bm->stackdepth = 1;
|
||||||
bm->totflags = 1;
|
bm->totflags = 0;
|
||||||
|
|
||||||
CustomData_reset(&bm->vdata);
|
CustomData_reset(&bm->vdata);
|
||||||
CustomData_reset(&bm->edata);
|
CustomData_reset(&bm->edata);
|
||||||
@@ -143,7 +171,9 @@ void BM_mesh_data_free(BMesh *bm)
|
|||||||
BLI_mempool_destroy(bm->fpool);
|
BLI_mempool_destroy(bm->fpool);
|
||||||
|
|
||||||
/* destroy flag pool */
|
/* destroy flag pool */
|
||||||
BLI_mempool_destroy(bm->toolflagpool);
|
if (bm->toolflagpool) {
|
||||||
|
BLI_mempool_destroy(bm->toolflagpool);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_BMESH_HOLES
|
#ifdef USE_BMESH_HOLES
|
||||||
BLI_mempool_destroy(bm->looplistpool);
|
BLI_mempool_destroy(bm->looplistpool);
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
|
|
||||||
struct BMAllocTemplate;
|
struct BMAllocTemplate;
|
||||||
|
|
||||||
|
void BM_mesh_elem_toolflags_ensure(BMesh *bm);
|
||||||
BMesh *BM_mesh_create(struct BMAllocTemplate *allocsize);
|
BMesh *BM_mesh_create(struct BMAllocTemplate *allocsize);
|
||||||
|
|
||||||
void BM_mesh_free(BMesh *bm);
|
void BM_mesh_free(BMesh *bm);
|
||||||
@@ -58,4 +59,8 @@ typedef struct BMAllocTemplate {
|
|||||||
extern BMAllocTemplate bm_mesh_allocsize_default;
|
extern BMAllocTemplate bm_mesh_allocsize_default;
|
||||||
extern BMAllocTemplate bm_mesh_chunksize_default;
|
extern BMAllocTemplate bm_mesh_chunksize_default;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
BM_MESH_CREATE_USE_TOOLFLAGS = (1 << 0)
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* __BMESH_MESH_H__ */
|
#endif /* __BMESH_MESH_H__ */
|
||||||
|
@@ -101,6 +101,8 @@ void BMO_push(BMesh *bm, BMOperator *UNUSED(op))
|
|||||||
{
|
{
|
||||||
bm->stackdepth++;
|
bm->stackdepth++;
|
||||||
|
|
||||||
|
BLI_assert(bm->totflags > 0);
|
||||||
|
|
||||||
/* add flag layer, if appropriate */
|
/* add flag layer, if appropriate */
|
||||||
if (bm->stackdepth > 1)
|
if (bm->stackdepth > 1)
|
||||||
bmo_flag_layer_alloc(bm);
|
bmo_flag_layer_alloc(bm);
|
||||||
@@ -172,7 +174,9 @@ void BMO_op_init(BMesh *bm, BMOperator *op, const int flag, const char *opname)
|
|||||||
*/
|
*/
|
||||||
void BMO_op_exec(BMesh *bm, BMOperator *op)
|
void BMO_op_exec(BMesh *bm, BMOperator *op)
|
||||||
{
|
{
|
||||||
|
/* allocate tool flags on demand */
|
||||||
|
BM_mesh_elem_toolflags_ensure(bm);
|
||||||
|
|
||||||
BMO_push(bm, op);
|
BMO_push(bm, op);
|
||||||
|
|
||||||
if (bm->stackdepth == 2)
|
if (bm->stackdepth == 2)
|
||||||
@@ -1056,7 +1060,9 @@ static void bmo_flag_layer_alloc(BMesh *bm)
|
|||||||
|
|
||||||
/* store memcpy size for reuse */
|
/* store memcpy size for reuse */
|
||||||
const size_t old_totflags_size = (bm->totflags * sizeof(BMFlagLayer));
|
const size_t old_totflags_size = (bm->totflags * sizeof(BMFlagLayer));
|
||||||
|
|
||||||
|
BLI_assert(oldpool != NULL);
|
||||||
|
|
||||||
bm->totflags++;
|
bm->totflags++;
|
||||||
|
|
||||||
/* allocate new flag poo */
|
/* allocate new flag poo */
|
||||||
|
@@ -181,7 +181,7 @@ static BMFace *copy_face(BMOperator *op, BMesh *source_mesh,
|
|||||||
* Internal Copy function.
|
* Internal Copy function.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void BKE_mesh_copy(BMOperator *op, BMesh *source, BMesh *target)
|
static void bmo_mesh_copy(BMOperator *op, BMesh *source, BMesh *target)
|
||||||
{
|
{
|
||||||
|
|
||||||
BMVert *v = NULL, *v2;
|
BMVert *v = NULL, *v2;
|
||||||
@@ -326,7 +326,7 @@ void bmo_duplicate_exec(BMesh *bm, BMOperator *op)
|
|||||||
BMO_slot_buffer_flag_enable(bm, dupeop, "geom", BM_ALL, DUPE_INPUT);
|
BMO_slot_buffer_flag_enable(bm, dupeop, "geom", BM_ALL, DUPE_INPUT);
|
||||||
|
|
||||||
/* use the internal copy function */
|
/* use the internal copy function */
|
||||||
BKE_mesh_copy(dupeop, bm, bm2);
|
bmo_mesh_copy(dupeop, bm, bm2);
|
||||||
|
|
||||||
/* Output */
|
/* Output */
|
||||||
/* First copy the input buffers to output buffers - original data */
|
/* First copy the input buffers to output buffers - original data */
|
||||||
|
@@ -1110,10 +1110,13 @@ BMesh *BME_bevel(BMesh *bm, float value, int res, int options, int defgrp_index,
|
|||||||
td = BME_init_transdata(BLI_MEMARENA_STD_BUFSIZE);
|
td = BME_init_transdata(BLI_MEMARENA_STD_BUFSIZE);
|
||||||
/* recursion math courtesy of Martin Poirier (theeth) */
|
/* recursion math courtesy of Martin Poirier (theeth) */
|
||||||
for (i = 0; i < res - 1; i++) {
|
for (i = 0; i < res - 1; i++) {
|
||||||
if (i == 0) fac += 1.0 / 3.0; else fac += 1.0 / (3.0 * i * 2.0);
|
if (i == 0) fac += 1.0 / 3.0;
|
||||||
|
else fac += 1.0 / (3.0 * i * 2.0);
|
||||||
}
|
}
|
||||||
d = 1.0 / fac;
|
d = 1.0 / fac;
|
||||||
|
|
||||||
|
BM_mesh_elem_toolflags_ensure(bm);
|
||||||
|
|
||||||
for (i = 0; i < res || (res == 0 && i == 0); i++) {
|
for (i = 0; i < res || (res == 0 && i == 0); i++) {
|
||||||
BMO_push(bm, NULL);
|
BMO_push(bm, NULL);
|
||||||
BME_bevel_initialize(bm, options, defgrp_index, angle, td);
|
BME_bevel_initialize(bm, options, defgrp_index, angle, td);
|
||||||
|
@@ -3006,6 +3006,8 @@ static int mesh_separate_tagged(Main *bmain, Scene *scene, Base *base_old, BMesh
|
|||||||
BMesh *bm_new;
|
BMesh *bm_new;
|
||||||
|
|
||||||
bm_new = BM_mesh_create(&bm_mesh_allocsize_default);
|
bm_new = BM_mesh_create(&bm_mesh_allocsize_default);
|
||||||
|
BM_mesh_elem_toolflags_ensure(bm_new); /* needed for 'duplicate' bmo */
|
||||||
|
|
||||||
CustomData_copy(&bm_old->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
|
CustomData_copy(&bm_old->vdata, &bm_new->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
|
||||||
CustomData_copy(&bm_old->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0);
|
CustomData_copy(&bm_old->edata, &bm_new->edata, CD_MASK_BMESH, CD_CALLOC, 0);
|
||||||
CustomData_copy(&bm_old->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
|
CustomData_copy(&bm_old->ldata, &bm_new->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
|
||||||
|
@@ -408,6 +408,7 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
|
|||||||
* cleaner way to do this. One possibility: a "mirror" BMOp would
|
* cleaner way to do this. One possibility: a "mirror" BMOp would
|
||||||
* certainly help by compressing it all into one top-level BMOp that
|
* certainly help by compressing it all into one top-level BMOp that
|
||||||
* executes a lot of second-level BMOps. */
|
* executes a lot of second-level BMOps. */
|
||||||
|
BM_mesh_elem_toolflags_ensure(bm);
|
||||||
BMO_push(bm, NULL);
|
BMO_push(bm, NULL);
|
||||||
bmesh_edit_begin(bm, 0);
|
bmesh_edit_begin(bm, 0);
|
||||||
|
|
||||||
|
@@ -143,6 +143,8 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *UNUSED(ob),
|
|||||||
BM_mesh_bevel(bm, bmd->value, segments);
|
BM_mesh_bevel(bm, bmd->value, segments);
|
||||||
|
|
||||||
result = CDDM_from_bmesh(bm, TRUE);
|
result = CDDM_from_bmesh(bm, TRUE);
|
||||||
|
|
||||||
|
BLI_assert(bm->toolflagpool == NULL); /* make sure we never alloc'd this */
|
||||||
BM_mesh_free(bm);
|
BM_mesh_free(bm);
|
||||||
|
|
||||||
CDDM_calc_normals(result);
|
CDDM_calc_normals(result);
|
||||||
|
@@ -186,6 +186,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
|
|||||||
/* update for display only */
|
/* update for display only */
|
||||||
dmd->face_count = bm->totface;
|
dmd->face_count = bm->totface;
|
||||||
result = CDDM_from_bmesh(bm, FALSE);
|
result = CDDM_from_bmesh(bm, FALSE);
|
||||||
|
BLI_assert(bm->toolflagpool == NULL); /* make sure we never alloc'd this */
|
||||||
BM_mesh_free(bm);
|
BM_mesh_free(bm);
|
||||||
|
|
||||||
#ifdef USE_TIMEIT
|
#ifdef USE_TIMEIT
|
||||||
|
@@ -67,8 +67,7 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
|
|||||||
float threshold = cosf((emd->split_angle + 0.00001f) * (float)M_PI / 180.0f);
|
float threshold = cosf((emd->split_angle + 0.00001f) * (float)M_PI / 180.0f);
|
||||||
|
|
||||||
bm = DM_to_bmesh(dm);
|
bm = DM_to_bmesh(dm);
|
||||||
|
BM_mesh_elem_toolflags_ensure(bm);
|
||||||
BMO_push(bm, NULL);
|
|
||||||
|
|
||||||
if (emd->flags & MOD_EDGESPLIT_FROMANGLE) {
|
if (emd->flags & MOD_EDGESPLIT_FROMANGLE) {
|
||||||
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
|
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
|
||||||
@@ -103,8 +102,6 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj
|
|||||||
|
|
||||||
BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
|
BMO_op_callf(bm, BMO_FLAG_DEFAULTS,
|
||||||
"split_edges edges=%fe", EDGE_MARK);
|
"split_edges edges=%fe", EDGE_MARK);
|
||||||
|
|
||||||
BMO_pop(bm);
|
|
||||||
|
|
||||||
/* BM_mesh_validate(bm); */ /* for troubleshooting */
|
/* BM_mesh_validate(bm); */ /* for troubleshooting */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user