Fixed broken customdata interpolation in dyntopo collapse.

Also added support for uvs to dyntopo gpu buffer building code.
This commit is contained in:
Joseph Eagar 2020-10-25 04:31:06 -07:00
parent 3214b1114f
commit 5c6407c268
2 changed files with 93 additions and 13 deletions

View File

@ -1605,7 +1605,53 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
* really buy anything. */
BLI_buffer_clear(deleted_faces);
#define MAX_LS 24
BMLoop *l;
#if 1 // def DYNTOPO_CD_INTERP
BMLoop *ls[MAX_LS];
int totl = 0;
BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_del) {
if (totl >= MAX_LS) {
break;
}
ls[totl++] = l;
}
BM_LOOPS_OF_VERT_ITER_END;
BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_conn) {
if (totl >= MAX_LS) {
break;
}
ls[totl++] = l;
}
BM_LOOPS_OF_VERT_ITER_END;
void *blocks[MAX_LS];
float ws[MAX_LS], w = totl > 1 ? 1.0f / (float)(totl - 1) : 1.0f;
for (int i = 0; i < totl - 1; i++) {
blocks[i] = ls[i + 1]->head.data;
ws[i] = w;
}
if (totl > 1) {
CustomData_bmesh_interp(&pbvh->bm->ldata, blocks, ws, NULL, totl - 1, ls[0]->head.data);
BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_del) {
CustomData_bmesh_copy_data(
&pbvh->bm->ldata, &pbvh->bm->ldata, ls[0]->head.data, &l->head.data);
}
BM_LOOPS_OF_VERT_ITER_END;
BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_conn) {
CustomData_bmesh_copy_data(
&pbvh->bm->ldata, &pbvh->bm->ldata, ls[0]->head.data, &l->head.data);
}
BM_LOOPS_OF_VERT_ITER_END;
}
#endif
BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_del) {
BMFace *existing_face;
@ -1647,14 +1693,14 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
BMFace *f2 = pbvh_bmesh_face_create(pbvh, ni, v_tri, e_tri, f);
#ifdef DYNTOPO_CD_INTERP
BMLoop *l2 = f2->l_first;
CustomData_bmesh_copy_data(&pbvh->bm->pdata, &pbvh->bm->pdata, f->head.data, &f2->head.data);
CustomData_bmesh_copy_data(&pbvh->bm->ldata, &pbvh->bm->ldata, l->head.data, &l2->head.data);
CustomData_bmesh_copy_data(
&pbvh->bm->pdata, &pbvh->bm->pdata, f->head.data, &f2->head.data);
&pbvh->bm->ldata, &pbvh->bm->ldata, l->next->head.data, &l2->next->head.data);
CustomData_bmesh_copy_data(
&pbvh->bm->ldata, &pbvh->bm->ldata, l->head.data, &f2->l_first->head.data);
CustomData_bmesh_copy_data(
&pbvh->bm->ldata, &pbvh->bm->ldata, l->next->head.data, &f2->l_first->next->head.data);
CustomData_bmesh_copy_data(
&pbvh->bm->ldata, &pbvh->bm->ldata, l->prev->head.data, &f2->l_first->prev->head.data);
&pbvh->bm->ldata, &pbvh->bm->ldata, l->prev->head.data, &l2->prev->head.data);
#endif
/* Ensure that v_conn is in the new face's node */
if (!BLI_table_gset_haskey(n->bm_unique_verts, v_conn)) {

View File

@ -101,7 +101,7 @@ struct GPU_PBVH_Buffers {
static struct {
GPUVertFormat format;
uint pos, nor, msk, col, fset;
uint pos, nor, msk, col, fset, uv;
} g_vbo_id = {{0}};
/** \} */
@ -125,6 +125,13 @@ void gpu_pbvh_init()
&g_vbo_id.format, "c", GPU_COMP_U16, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
g_vbo_id.fset = GPU_vertformat_attr_add(
&g_vbo_id.format, "fset", GPU_COMP_U8, 3, GPU_FETCH_INT_TO_FLOAT_UNIT);
g_vbo_id.uv = GPU_vertformat_attr_add(
&g_vbo_id.format, "uvs", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
GPU_vertformat_alias_add(&g_vbo_id.format, "texCoord");
GPU_vertformat_alias_add(&g_vbo_id.format, "u");
GPU_vertformat_alias_add(&g_vbo_id.format, "au");
}
}
@ -932,6 +939,7 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
const int update_flags,
const int cd_vert_node_offset)
{
const bool have_uv = CustomData_has_layer(&bm->ldata, CD_MLOOPUV);
const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0;
const bool show_vcol = (update_flags & GPU_PBVH_BUFFERS_SHOW_VCOL) != 0;
int tottri, totvert;
@ -941,7 +949,8 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
/* Count visible triangles */
tottri = gpu_bmesh_face_visible_count(bm_faces);
if (buffers->smooth) {
// XXX disable indexed verts for now
if (0 && buffers->smooth) {
/* Count visible vertices */
totvert = gpu_bmesh_vert_visible_count(bm_unique_verts, bm_other_verts);
}
@ -963,6 +972,7 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
/* TODO, make mask layer optional for bmesh buffer */
const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);
const int cd_vcol_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
const int cd_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
/* Fill vertex buffer */
if (!gpu_pbvh_vert_buf_data_set(buffers, totvert)) {
@ -972,7 +982,7 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
int v_index = 0;
if (buffers->smooth) {
if (buffers->smooth && 0) {
/* Fill the vertex and triangle buffer in one pass over faces. */
GPUIndexBufBuilder elb, elb_lines;
GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottri, totvert);
@ -1044,6 +1054,8 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
BMVert *v[3];
BMLoop *l[3] = {f->l_first, f->l_first->next, f->l_first->prev};
float fmask = 0.0f;
int i;
@ -1060,17 +1072,39 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
GPU_indexbuf_add_line_verts(&elb_lines, v_index + 2, v_index + 0);
for (i = 0; i < 3; i++) {
float *no = buffers->smooth ? v[i]->no : f->no;
gpu_bmesh_vert_to_buffer_copy(v[i],
buffers->vert_buf,
v_index++,
f->no,
v_index,
no,
&fmask,
cd_vert_mask_offset,
cd_vert_node_offset,
show_mask,
show_vcol,
false,
&empty_mask,
cd_vcol_offset);
-1);
if (cd_vcol_offset >= 0) {
ushort vcol[4];
MLoopCol *ml = BM_ELEM_CD_GET_VOID_P(l[i], cd_vcol_offset);
vcol[0] = ml->r * 257;
vcol[1] = ml->g * 257;
vcol[2] = ml->b * 257;
vcol[3] = ml->a * 257;
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, v_index, vcol);
}
if (have_uv) {
MLoopUV *mu = BM_ELEM_CD_GET_VOID_P(l[i], cd_uv_offset);
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.uv, v_index, mu->uv);
}
v_index++;
}
}
}