Sculpt dyntopo: Added a function to add multiple customdata
layers to a bmesh at once. Helpful since bmesh customdata layers are allocated in single blocks, thus adding layers individually can lead to lots of memory copying.
This commit is contained in:
parent
dba4f30328
commit
27986e9b56
|
@ -1336,6 +1336,102 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
|
|||
}
|
||||
}
|
||||
|
||||
ATTR_NO_OPT void BM_data_layers_ensure(BMesh *bm,
|
||||
CustomData *data,
|
||||
BMCustomLayerReq *layers,
|
||||
int totlayer)
|
||||
{
|
||||
bool modified = false;
|
||||
CustomData old = *data;
|
||||
CustomData temp;
|
||||
CustomDataMask mask = 0;
|
||||
|
||||
if (old.layers) {
|
||||
old.layers = MEM_dupallocN(old.layers);
|
||||
}
|
||||
|
||||
memset(&temp, 0, sizeof(temp));
|
||||
CustomData_reset(&temp);
|
||||
|
||||
for (int i = 0; i < totlayer; i++) {
|
||||
BMCustomLayerReq *req = layers + i;
|
||||
int idx;
|
||||
|
||||
mask |= 1ULL << (CustomDataMask)req->type;
|
||||
|
||||
if (req->name) {
|
||||
idx = CustomData_get_named_layer_index(data, req->type, req->name);
|
||||
}
|
||||
else {
|
||||
idx = CustomData_get_layer_index(data, req->type);
|
||||
}
|
||||
|
||||
if (idx < 0) {
|
||||
modified = true;
|
||||
|
||||
if (req->name) {
|
||||
CustomData_add_layer_named(&temp, req->type, CD_ASSIGN, NULL, 0, req->name);
|
||||
}
|
||||
else {
|
||||
CustomData_add_layer(&temp, req->type, CD_ASSIGN, NULL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int htype;
|
||||
if (data == &bm->vdata) {
|
||||
htype = BM_VERT;
|
||||
}
|
||||
else if (data == &bm->edata) {
|
||||
htype = BM_EDGE;
|
||||
}
|
||||
else if (data == &bm->ldata) {
|
||||
htype = BM_LOOP;
|
||||
}
|
||||
else if (data == &bm->pdata) {
|
||||
htype = BM_FACE;
|
||||
}
|
||||
else {
|
||||
printf("error in %s!\n", __func__);
|
||||
CustomData_free(&temp, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
CustomData_merge(&temp, data, mask, CD_ASSIGN, 0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < totlayer; i++) {
|
||||
BMCustomLayerReq *req = layers + i;
|
||||
int idx;
|
||||
|
||||
mask |= 1 << req->type;
|
||||
|
||||
if (req->name) {
|
||||
idx = CustomData_get_named_layer_index(data, req->type, req->name);
|
||||
}
|
||||
else {
|
||||
idx = CustomData_get_layer_index(data, req->type);
|
||||
}
|
||||
|
||||
data->layers[idx].flag |= req->flag;
|
||||
}
|
||||
|
||||
if (modified) {
|
||||
/* the pool is now owned by olddata and must not be shared */
|
||||
data->pool = NULL;
|
||||
|
||||
update_data_blocks(bm, &old, data);
|
||||
bm_update_idmap_cdlayers(bm);
|
||||
}
|
||||
|
||||
if (old.layers) {
|
||||
MEM_freeN(old.layers);
|
||||
}
|
||||
|
||||
CustomData_free(&temp, 0);
|
||||
}
|
||||
|
||||
void BM_data_layer_add(BMesh *bm, CustomData *data, int type)
|
||||
{
|
||||
CustomData olddata;
|
||||
|
|
|
@ -24,6 +24,12 @@
|
|||
struct LinkNode;
|
||||
struct MemArena;
|
||||
|
||||
typedef struct BMCustomLayerReq {
|
||||
int type;
|
||||
char *name; // can be NULL
|
||||
int flag;
|
||||
} BMCustomLayerReq;
|
||||
|
||||
void BM_face_multires_stitch(BMesh *bm, BMFace *f);
|
||||
void BM_loop_interp_multires_ex(BMesh *bm,
|
||||
BMLoop *l_dst,
|
||||
|
@ -53,6 +59,9 @@ void BM_data_interp_face_vert_edge(BMesh *bm,
|
|||
BMVert *v,
|
||||
BMEdge *e,
|
||||
const float fac);
|
||||
|
||||
void BM_data_layers_ensure(BMesh *bm, CustomData *data, BMCustomLayerReq *layers, int totlayer);
|
||||
|
||||
void BM_data_layer_add(BMesh *bm, CustomData *data, int type);
|
||||
void BM_data_layer_add_named(BMesh *bm, CustomData *data, int type, const char *name);
|
||||
void BM_data_layer_free(BMesh *bm, CustomData *data, int type);
|
||||
|
|
|
@ -296,18 +296,11 @@ void SCULPT_dyntopo_node_layers_add(SculptSession *ss)
|
|||
int cd_origco_index, cd_origno_index, cd_origvcol_index = -1;
|
||||
bool have_vcol = CustomData_has_layer(&ss->bm->vdata, CD_PROP_COLOR);
|
||||
|
||||
if (!CustomData_has_layer(&ss->bm->vdata, CD_DYNTOPO_VERT)) {
|
||||
BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_DYNTOPO_VERT);
|
||||
BMCustomLayerReq vlayers[] = {{CD_PAINT_MASK, NULL, 0},
|
||||
{CD_DYNTOPO_VERT, NULL, CD_FLAG_TEMPORARY},
|
||||
{CD_PROP_INT32, dyntopop_node_idx_layer_id, CD_FLAG_TEMPORARY}};
|
||||
|
||||
int cd_dyn_vert = CustomData_get_layer_index(&ss->bm->vdata, CD_DYNTOPO_VERT);
|
||||
ss->bm->vdata.layers[cd_dyn_vert].flag |= CD_FLAG_TEMPORARY;
|
||||
}
|
||||
|
||||
cd_node_layer_index = CustomData_get_named_layer_index(
|
||||
&ss->bm->vdata, CD_PROP_INT32, dyntopop_node_idx_layer_id);
|
||||
if (cd_node_layer_index == -1) {
|
||||
BM_data_layer_add_named(ss->bm, &ss->bm->vdata, CD_PROP_INT32, dyntopop_node_idx_layer_id);
|
||||
}
|
||||
BM_data_layers_ensure(ss->bm, &ss->bm->vdata, vlayers, 3);
|
||||
|
||||
cd_face_node_layer_index = CustomData_get_named_layer_index(
|
||||
&ss->bm->pdata, CD_PROP_INT32, dyntopop_node_idx_layer_id);
|
||||
|
@ -513,8 +506,6 @@ void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene
|
|||
#endif
|
||||
SCULPT_dynamic_topology_triangulate(ss, ss->bm);
|
||||
|
||||
BM_data_layer_add(ss->bm, &ss->bm->vdata, CD_PAINT_MASK);
|
||||
|
||||
SCULPT_dyntopo_node_layers_add(ss);
|
||||
SCULPT_dyntopo_save_origverts(ss);
|
||||
|
||||
|
@ -527,10 +518,12 @@ void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene
|
|||
|
||||
// convert layer brush data
|
||||
if (ss->persistent_base) {
|
||||
SCULPT_dyntopo_ensure_templayer(ss, CD_PROP_FLOAT3, SCULPT_LAYER_PERS_CO);
|
||||
SCULPT_dyntopo_ensure_templayer(ss, CD_PROP_FLOAT3, SCULPT_LAYER_PERS_NO);
|
||||
SCULPT_dyntopo_ensure_templayer(ss, CD_PROP_FLOAT, SCULPT_LAYER_PERS_DISP);
|
||||
SCULPT_dyntopo_ensure_templayer(ss, CD_PROP_FLOAT, SCULPT_LAYER_DISP);
|
||||
BMCustomLayerReq layers[] = {{CD_PROP_FLOAT3, SCULPT_LAYER_PERS_CO, CD_FLAG_TEMPORARY},
|
||||
{CD_PROP_FLOAT3, SCULPT_LAYER_PERS_NO, CD_FLAG_TEMPORARY},
|
||||
{CD_PROP_FLOAT, SCULPT_LAYER_PERS_DISP, CD_FLAG_TEMPORARY},
|
||||
{CD_PROP_FLOAT, SCULPT_LAYER_DISP, CD_FLAG_TEMPORARY}};
|
||||
|
||||
BM_data_layers_ensure(ss->bm, &ss->bm->vdata, layers, 4);
|
||||
|
||||
cd_pers_co = SCULPT_dyntopo_get_templayer(ss, CD_PROP_FLOAT3, SCULPT_LAYER_PERS_CO);
|
||||
cd_pers_no = SCULPT_dyntopo_get_templayer(ss, CD_PROP_FLOAT3, SCULPT_LAYER_PERS_NO);
|
||||
|
|
Loading…
Reference in New Issue