Sculpt-dev: fix memory corruption
* Forgot to change the face area customdata layer to CD_FLOAT2 everywhere, leading to nasty memory corruption.
This commit is contained in:
parent
e4b6180c4e
commit
a5c3d3476c
|
@ -1306,7 +1306,7 @@ void BKE_pbvh_bmesh_add_face(PBVH *pbvh, struct BMFace *f, bool log_face, bool f
|
|||
{
|
||||
bm_logstack_push();
|
||||
|
||||
int ni = -1;
|
||||
int ni = DYNTOPO_NODE_NONE;
|
||||
|
||||
if (force_tree_walk) {
|
||||
bke_pbvh_insert_face(pbvh, f);
|
||||
|
@ -3955,6 +3955,7 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
lnext = l->radial_next;
|
||||
|
||||
bool fbad = false;
|
||||
#if 1
|
||||
do {
|
||||
|
||||
if (l2->v == l2->next->v) {
|
||||
|
@ -3973,6 +3974,7 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
break;
|
||||
}
|
||||
} while ((l2 = l2->next) != l->f->l_first);
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
@ -5443,39 +5445,48 @@ static void pbvh_split_edges(EdgeQueueContext *eq_ctx,
|
|||
ni = BM_ELEM_CD_GET_INT(v2, pbvh->cd_vert_node_offset);
|
||||
}
|
||||
|
||||
// this should never happen
|
||||
if (true || ni == DYNTOPO_NODE_NONE) {
|
||||
BMIter fiter;
|
||||
BMFace *f;
|
||||
if (ni >= pbvh->totnode || !(pbvh->nodes[ni].flag & PBVH_Leaf)) {
|
||||
printf("%s: error\n", __func__);
|
||||
}
|
||||
/* this should rarely happen */
|
||||
// if (ni < 0 || ni >= pbvh->totnode || !(pbvh->nodes[ni].flag & PBVH_Leaf)) {
|
||||
if (ni == DYNTOPO_NODE_NONE) {
|
||||
ni = DYNTOPO_NODE_NONE;
|
||||
|
||||
for (int j = 0; j < 3; j++) {
|
||||
for (int j = 0; j < 2; j++) {
|
||||
BMVert *v = NULL;
|
||||
|
||||
switch (j) {
|
||||
case 0:
|
||||
v = newv;
|
||||
break;
|
||||
case 1:
|
||||
v = v1;
|
||||
break;
|
||||
case 2:
|
||||
case 1:
|
||||
v = v2;
|
||||
break;
|
||||
}
|
||||
|
||||
BM_ITER_ELEM (f, &fiter, v, BM_FACES_OF_VERT) {
|
||||
int ni2 = BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset);
|
||||
if (!v->e) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ni2 != DYNTOPO_NODE_NONE) {
|
||||
ni = ni2;
|
||||
BMEdge *e2 = v->e;
|
||||
do {
|
||||
if (!e2->l) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ni != DYNTOPO_NODE_NONE) {
|
||||
break;
|
||||
}
|
||||
BMLoop *l = e2->l;
|
||||
do {
|
||||
int ni2 = BM_ELEM_CD_GET_INT(l->f, pbvh->cd_face_node_offset);
|
||||
|
||||
if (ni2 >= 0 && ni2 < pbvh->totnode && (pbvh->nodes[ni2].flag & PBVH_Leaf)) {
|
||||
ni = ni2;
|
||||
goto outerbreak;
|
||||
}
|
||||
} while ((l = l->radial_next) != e2->l);
|
||||
} while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
|
||||
}
|
||||
outerbreak:;
|
||||
}
|
||||
|
||||
if (ni != DYNTOPO_NODE_NONE) {
|
||||
|
@ -5520,6 +5531,11 @@ static void pbvh_split_edges(EdgeQueueContext *eq_ctx,
|
|||
|
||||
int ni = BM_ELEM_CD_GET_INT(f, pbvh->cd_face_node_offset);
|
||||
|
||||
if (ni < 0 || ni >= pbvh->totnode || !(pbvh->nodes[ni].flag & PBVH_Leaf)) {
|
||||
printf("%s: error!\n", __func__);
|
||||
ni = DYNTOPO_NODE_NONE;
|
||||
}
|
||||
|
||||
BMLoop *l = f->l_first;
|
||||
int j = 0;
|
||||
do {
|
||||
|
@ -5531,7 +5547,7 @@ static void pbvh_split_edges(EdgeQueueContext *eq_ctx,
|
|||
|
||||
int flen = j;
|
||||
|
||||
if (mask >= (int)ARRAY_SIZE(splitmap)) {
|
||||
if (mask < 0 || mask >= (int)ARRAY_SIZE(splitmap)) {
|
||||
printf("splitmap error!\n");
|
||||
continue;
|
||||
}
|
||||
|
@ -5715,7 +5731,7 @@ DynTopoState *BKE_dyntopo_init(BMesh *bm, PBVH *existing_pbvh)
|
|||
{CD_PROP_INT32, dyntopop_node_idx_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY}};
|
||||
|
||||
BMCustomLayerReq flayers[] = {
|
||||
{CD_PROP_FLOAT, dyntopop_faces_areas_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY},
|
||||
{CD_PROP_FLOAT2, dyntopop_faces_areas_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY},
|
||||
{CD_SCULPT_FACE_SETS, NULL, 0},
|
||||
{CD_PROP_INT32, dyntopop_node_idx_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY}};
|
||||
|
||||
|
@ -5733,7 +5749,7 @@ DynTopoState *BKE_dyntopo_init(BMesh *bm, PBVH *existing_pbvh)
|
|||
&bm->pdata, CD_PROP_INT32, dyntopop_node_idx_layer_id);
|
||||
|
||||
pbvh->cd_face_area = CustomData_get_named_offset(
|
||||
&bm->pdata, CD_PROP_FLOAT, dyntopop_faces_areas_layer_id);
|
||||
&bm->pdata, CD_PROP_FLOAT2, dyntopop_faces_areas_layer_id);
|
||||
|
||||
pbvh->cd_sculpt_vert = CustomData_get_offset(&bm->vdata, CD_DYNTOPO_VERT);
|
||||
pbvh->cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
|
||||
|
|
|
@ -2938,7 +2938,7 @@ void BKE_sculptsession_bmesh_add_layers(Object *ob)
|
|||
{CD_DYNTOPO_VERT, NULL, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY},
|
||||
{CD_PROP_INT32, dyntopop_node_idx_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY}};
|
||||
|
||||
BM_data_layers_ensure(ss->bm, &ss->bm->vdata, vlayers, 3);
|
||||
BM_data_layers_ensure(ss->bm, &ss->bm->vdata, vlayers, ARRAY_SIZE(vlayers));
|
||||
|
||||
ss->cd_vert_mask_offset = CustomData_get_offset(&ss->bm->vdata, CD_PAINT_MASK);
|
||||
|
||||
|
@ -2946,7 +2946,7 @@ void BKE_sculptsession_bmesh_add_layers(Object *ob)
|
|||
{CD_PROP_INT32, dyntopop_node_idx_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY},
|
||||
{CD_PROP_FLOAT2, dyntopop_faces_areas_layer_id, CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY},
|
||||
};
|
||||
BM_data_layers_ensure(ss->bm, &ss->bm->pdata, flayers, 2);
|
||||
BM_data_layers_ensure(ss->bm, &ss->bm->pdata, flayers, ARRAY_SIZE(flayers));
|
||||
|
||||
// get indices again, as they might have changed after adding new layers
|
||||
cd_node_layer_index = CustomData_get_named_layer_index(
|
||||
|
@ -2971,8 +2971,9 @@ void BKE_sculptsession_bmesh_add_layers(Object *ob)
|
|||
ss->bm->pdata.layers[cd_face_node_layer_index].flag |= CD_FLAG_TEMPORARY | CD_FLAG_NOCOPY;
|
||||
ss->cd_faceset_offset = CustomData_get_offset(&ss->bm->pdata, CD_SCULPT_FACE_SETS);
|
||||
|
||||
ss->cd_face_areas = CustomData_get_named_layer(
|
||||
&ss->bm->pdata, CD_PROP_FLOAT, dyntopop_faces_areas_layer_id);
|
||||
ss->cd_face_areas = CustomData_get_named_layer_index(
|
||||
&ss->bm->pdata, CD_PROP_FLOAT2, dyntopop_faces_areas_layer_id);
|
||||
|
||||
ss->cd_face_areas = ss->bm->pdata.layers[ss->cd_face_areas].offset;
|
||||
|
||||
AttributeDomain domain;
|
||||
|
|
|
@ -5649,7 +5649,7 @@ void pbvh_bmesh_cache_test(CacheParams *params, BMesh **r_bm, PBVH **r_pbvh_out)
|
|||
int cd_face_node = CustomData_get_named_layer_index(
|
||||
&bm->pdata, CD_PROP_INT32, "__dyntopo_face_node");
|
||||
int cd_face_area = CustomData_get_named_layer_index(
|
||||
&bm->pdata, CD_PROP_FLOAT, "__dyntopo_face_areas");
|
||||
&bm->pdata, CD_PROP_FLOAT2, "__dyntopo_face_areas");
|
||||
|
||||
cd_vert_node = bm->vdata.layers[cd_vert_node].offset;
|
||||
cd_face_node = bm->pdata.layers[cd_face_node].offset;
|
||||
|
@ -6070,7 +6070,8 @@ static void pbvh_bmesh_fetch_cdrefs(PBVH *pbvh)
|
|||
idx = CustomData_get_named_layer_index(&bm->pdata, CD_PROP_INT32, dyntopop_node_idx_layer_id);
|
||||
pbvh->cd_face_node_offset = bm->pdata.layers[idx].offset;
|
||||
|
||||
idx = CustomData_get_named_layer_index(&bm->pdata, CD_PROP_FLOAT, dyntopop_faces_areas_layer_id);
|
||||
idx = CustomData_get_named_layer_index(
|
||||
&bm->pdata, CD_PROP_FLOAT2, dyntopop_faces_areas_layer_id);
|
||||
pbvh->cd_face_area = bm->pdata.layers[idx].offset;
|
||||
|
||||
pbvh->cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
|
||||
|
|
|
@ -3185,7 +3185,7 @@ BMVert *BM_log_edge_split_do(BMLog *log, BMEdge *e, BMVert *v, BMEdge **newe, fl
|
|||
|
||||
BM_log_edge_topo_pre(log, e);
|
||||
BMVert *newv = BM_edge_split(log->bm, e, v, newe, t);
|
||||
|
||||
|
||||
BM_log_edge_topo_post(log, e);
|
||||
BM_log_edge_added(log, *newe);
|
||||
|
||||
|
|
Loading…
Reference in New Issue