Sculpt: various uv-related fixed

* The dyntopo collapse function now
  properly snaps UVs, including at
  island boundaries.
* PBVHTriBufs are now split by UVs
  (and face sets); this turned out
  to be surprising easy.
* Also fixed a few bugs relating to
  hiding/revealing stuff.
This commit is contained in:
Joseph Eagar 2021-10-06 21:54:10 -07:00
parent c2f2a8260c
commit e11ba956d2
11 changed files with 232 additions and 78 deletions

View File

@ -505,6 +505,7 @@ void BKE_pbvh_bmesh_update_all_valence(PBVH *pbvh);
void BKE_pbvh_bmesh_flag_all_disk_sort(PBVH *pbvh);
bool BKE_pbvh_bmesh_mark_update_valence(PBVH *pbvh, SculptVertRef vertex);
void BKE_pbvh_node_mark_update_triangulation(PBVHNode *node);
void BKE_pbvh_node_mark_original_update(PBVHNode *node);
void BKE_pbvh_node_mark_update_tri_area(PBVHNode *node);
void BKE_pbvh_update_all_tri_areas(PBVH *pbvh);
@ -642,7 +643,8 @@ typedef struct PBVHVertexIter {
bool visible;
} PBVHVertexIter;
#define BKE_PBVH_SCULPTVERT(cd_sculpt_vert, v) ((MSculptVert *)BM_ELEM_CD_GET_VOID_P(v, cd_sculpt_vert))
#define BKE_PBVH_SCULPTVERT(cd_sculpt_vert, v) \
((MSculptVert *)BM_ELEM_CD_GET_VOID_P(v, cd_sculpt_vert))
void pbvh_vertex_iter_init(PBVH *pbvh, PBVHNode *node, PBVHVertexIter *vi, int mode);
@ -851,7 +853,7 @@ void BKE_pbvh_set_symmetry(PBVH *pbvh, int symmetry, int boundary_symmetry);
#if 0
typedef enum {
SCULPT_TEXTURE_UV = 1 << 0, // per-uv
// SCULPT_TEXTURE_PTEX?
SCULPT_TEXTURE_GRIDS = 1<<1
} SculptTextureType;
typedef int TexLayerRef;
@ -870,6 +872,8 @@ typedef struct SculptTextureDef {
void (*build_begin)(PBVH *pbvh, PBVHNode *node, TexLayerRef vdm);
void (*calc_bounds)(PBVH *pbvh, PBVHNode *node, float r_min[3], float r_max[3], TexLayerRef vdm);
/*vdms can cache data per node, which is freed to maintain memory limit.
they store cache in the same structure they return in buildNodeData.*/
void (*freeCachedData)(PBVH *pbvh, PBVHNode *node, TexLayerRef vdm);
@ -879,6 +883,8 @@ typedef struct SculptTextureDef {
void *(*buildNodeData)(PBVH *pbvh, PBVHNode *node);
bool (*validate)(PBVH *pbvh, TexLayerRef vdm);
void (*setVertexCos)(PBVH *pbvh, PBVHNode *node, SculptVertRef *verts, int totvert, TexLayerRef vdm);
void (*getPointsFromNode)(PBVH *pbvh,
PBVHNode *node,
TexLayerRef vdm,
@ -924,7 +930,7 @@ typedef struct SculptTextureDef {
PBVH *pbvh, PBVHNode *node, TexLayerRef vdm, TexPointRef *ids, int totid);
/*displacement texture stuff*/
// can be tangent, object space displacement, whatever
// can be tangent, object space displacement
void (*worldToDelta)(PBVH *pbvh, PBVHNode *node, TexLayerRef vdm, TexPointRef *ids, int totid);
void (*deltaToWorld)(PBVH *pbvh, PBVHNode *node, TexLayerRef vdm, TexPointRef *ids, int totid);
} SculptDisplacementDef;

View File

@ -298,6 +298,7 @@ static bool check_builtin_init()
SETCAT(topology_rake_projection, "Smoothing");
SETCAT(topology_rake_use_spacing, "Smoothing");
SETCAT(topology_rake_spacing, "Smoothing");
SETCAT(topology_rake_mode, "Smoothing");
SETCAT(boundary_smooth, "Smoothing");
SETCAT(fset_slide, "Smoothing");
@ -1367,6 +1368,7 @@ void BKE_brush_channelset_ui_init(Brush *brush, int tool)
case SCULPT_TOOL_SIMPLIFY:
SHOWCTX(autosmooth);
SHOWCTX(topology_rake);
SHOWCTX(topology_rake_mode);
break;
case SCULPT_TOOL_LAYER:
SHOWWRK(use_persistent);

View File

@ -3643,6 +3643,20 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
return;
}
int uvidx = pbvh->bm->ldata.typemap[CD_MLOOPUV];
CustomDataLayer *uv_layer = NULL;
int totuv = 0;
if (uvidx >= 0) {
uv_layer = pbvh->bm->ldata.layers + uvidx;
totuv = 0;
while (uvidx < pbvh->bm->ldata.totlayer && pbvh->bm->ldata.layers[uvidx].type == CD_MLOOPUV) {
uvidx++;
totuv++;
}
}
/*have to check edge flags directly, vertex flag test above isn't specific enough and
can sometimes let bad edges through*/
if ((mv1->flag & SCULPTVERT_SHARP_BOUNDARY) && (e->head.hflag & BM_ELEM_SMOOTH)) {
@ -3783,72 +3797,109 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
CustomData_bmesh_interp(&pbvh->bm->vdata, v_blocks, v_ws, NULL, 2, v_conn->head.data);
BM_ELEM_CD_SET_INT(v_conn, pbvh->cd_vert_node_offset, ni_conn);
}
BMLoop **ls = NULL;
void **blocks = NULL;
float *ws = NULL;
BLI_array_staticdeclare(ls, 64);
BLI_array_staticdeclare(blocks, 64);
BLI_array_staticdeclare(ws, 64);
// deal with UVs
if (e->l) {
const int lflag = BM_ELEM_TAG_ALT;
int totl = 0;
BMLoop *l = e->l;
BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_del) {
MSculptVert *mv_l = BKE_PBVH_SCULPTVERT(pbvh->cd_sculpt_vert, l->next->v);
MV_ADD_FLAG(mv_l, mupdateflag);
for (int step = 0; step < 2; step++) {
BMVert *v = step ? e->v2 : e->v1;
BMEdge *e2 = v->e;
BLI_array_append(ls, l);
totl++;
}
BM_LOOPS_OF_VERT_ITER_END;
if (!e2) {
continue;
}
BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_conn) {
MSculptVert *mv_l = BKE_PBVH_SCULPTVERT(pbvh->cd_sculpt_vert, l->next->v);
MV_ADD_FLAG(mv_l, mupdateflag);
do {
BMLoop *l2 = e2->l;
BLI_array_append(ls, l);
totl++;
}
BM_LOOPS_OF_VERT_ITER_END;
float w = totl > 0 ? 1.0f / (float)(totl) : 1.0f;
for (int i = 0; i < totl; i++) {
BLI_array_append(blocks, ls[i]->head.data);
BLI_array_append(ws, w);
}
// snap customdata
if (totl > 0) {
CustomData_bmesh_interp(
&pbvh->bm->ldata, (const void **)blocks, ws, NULL, totl, ls[0]->head.data);
//*
BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_del) {
BMLoop *l2 = l->v != v_del ? l->next : l;
if (l2 == ls[0]) {
if (!l2) {
continue;
}
CustomData_bmesh_copy_data(
&pbvh->bm->ldata, &pbvh->bm->ldata, ls[0]->head.data, &l2->head.data);
}
BM_LOOPS_OF_VERT_ITER_END;
do {
bool ok = true;
BMLoop *l3 = l2->v != v ? l2->next : l2;
BM_LOOPS_OF_VERT_ITER_BEGIN (l, v_conn) {
BMLoop *l2 = l->v != v_conn ? l->next : l;
if (l2 == ls[0]) {
continue;
}
CustomData_bmesh_copy_data(
&pbvh->bm->ldata, &pbvh->bm->ldata, ls[0]->head.data, &l2->head.data);
}
BM_LOOPS_OF_VERT_ITER_END;
//*/
/* store visit bits for each uv layer in l3->head.index */
l3->head.index = 0;
} while ((l2 = l2->radial_next) != e2->l);
} while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
}
float(*uv)[2] = alloca(sizeof(float) * 4 * totuv);
do {
BMLoop *ls2[2] = {l->head.data, l->next->head.data};
float ws2[2] = {0.5f, 0.5f};
if (!snap) {
const int axis = l->v == v_del ? 0 : 1;
ws2[axis] = 0.0f;
ws2[axis ^ 1] = 1.0f;
}
float uv[2][2];
for (int step = 0; uv_layer && step < 2; step++) {
BMLoop *l1 = step ? l : l->next;
for (int k = 0; k < totuv; k++) {
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l1, uv_layer[k].offset);
copy_v2_v2(uv[k * 2 + step], luv->uv);
}
}
CustomData_bmesh_interp(&pbvh->bm->ldata, ls2, ws2, NULL, 2, l->head.data);
CustomData_bmesh_copy_data(
&pbvh->bm->ldata, &pbvh->bm->ldata, l->head.data, &l->next->head.data);
for (int step = 0; totuv >= 0 && step < 2; step++) {
BMVert *v = step ? l->next->v : l->v;
BMLoop *l1 = step ? l->next : l;
BMEdge *e2 = v->e;
do {
BMLoop *l2 = e2->l;
do {
BMLoop *l3 = l2->v != v ? l2->next : l2;
if (!l3 || l3 == l1 || l3 == l || l3 == l->next) {
continue;
}
for (int k = 0; k < totuv; k++) {
const int flag = 1 << k;
if (l3->head.index & flag) {
continue;
}
const int cd_uv = uv_layer[k].offset;
MLoopUV *luv1 = BM_ELEM_CD_GET_VOID_P(l1, cd_uv);
MLoopUV *luv2 = BM_ELEM_CD_GET_VOID_P(l3, cd_uv);
float dx = luv2->uv[0] - uv[k * 2 + step][0];
float dy = luv2->uv[1] - uv[k * 2 + step][1];
float delta = dx * dx + dy * dy;
if (delta < 0.001) {
l3->head.index |= flag;
copy_v2_v2(luv2->uv, luv1->uv);
}
}
} while ((l2 = l2->radial_next) != e2->l);
} while ((e2 = BM_DISK_EDGE_NEXT(e2, v)) != v->e);
}
} while ((l = l->radial_next) != e->l);
}
validate_vert_faces(pbvh, pbvh->bm, v_conn, false, true);

View File

@ -4044,6 +4044,11 @@ PBVHNode *BKE_pbvh_get_node(PBVH *pbvh, int node)
return pbvh->nodes + node;
}
void BKE_pbvh_node_mark_update_triangulation(PBVHNode *node)
{
node->flag |= PBVH_UpdateTris;
}
void BKE_pbvh_node_mark_update_tri_area(PBVHNode *node)
{
node->flag |= PBVH_UpdateTriAreas;

View File

@ -41,6 +41,7 @@ Topology rake:
#include "MEM_guardedalloc.h"
#include "BLI_alloca.h"
#include "BLI_array.h"
#include "BLI_buffer.h"
#include "BLI_ghash.h"
@ -2149,25 +2150,30 @@ BLI_INLINE PBVHTri *pbvh_tribuf_add_tri(PBVHTriBuf *tribuf)
return tribuf->tris + tribuf->tottri - 1;
}
BLI_INLINE void pbvh_tribuf_add_vert(PBVHTriBuf *tribuf, SculptVertRef vertex)
BLI_INLINE void pbvh_tribuf_add_vert(PBVHTriBuf *tribuf, SculptVertRef vertex, BMLoop *l)
{
tribuf->totvert++;
tribuf->totloop++;
if (tribuf->totvert >= tribuf->verts_size) {
size_t newsize = (size_t)32 + (size_t)(tribuf->verts_size << 1);
if (!tribuf->verts) {
tribuf->verts = MEM_mallocN(sizeof(*tribuf->verts) * newsize, "tribuf verts");
tribuf->loops = MEM_mallocN(sizeof(*tribuf->loops) * newsize, "tribuf loops");
}
else {
tribuf->verts = MEM_reallocN_id(
tribuf->verts, sizeof(*tribuf->verts) * newsize, "tribuf verts");
tribuf->loops = MEM_reallocN_id(
tribuf->loops, sizeof(*tribuf->loops) * newsize, "tribuf loops");
}
tribuf->verts_size = newsize;
}
tribuf->verts[tribuf->totvert - 1] = vertex;
tribuf->loops[tribuf->totloop - 1] = (uintptr_t)l;
}
BLI_INLINE void pbvh_tribuf_add_edge(PBVHTriBuf *tribuf, int v1, int v2)
@ -2239,6 +2245,30 @@ static void pbvh_init_tribuf(PBVHNode *node, PBVHTriBuf *tribuf)
BLI_smallhash_init_ex(&tribuf->vertmap, node->bm_unique_verts->length);
}
static uintptr_t tri_loopkey(BMLoop *l, int mat_nr, int cd_fset, int cd_uvs[], int totuv)
{
uintptr_t key = (uintptr_t)mat_nr;
key ^= (uintptr_t)l->v;
if (cd_fset >= 0) {
key ^= BM_ELEM_CD_GET_INT(l->f, cd_fset);
}
for (int i = 0; i < totuv; i++) {
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_uvs[i]);
float snap = 4196.0f;
uintptr_t x = (uintptr_t)(luv->uv[0] * snap);
uintptr_t y = (uintptr_t)(luv->uv[1] * snap);
uintptr_t key2 = y * snap + x;
key ^= key2;
}
return key;
}
/* In order to perform operations on the original node coordinates
* (currently just raycast), store the node's triangles and vertices.
*
@ -2251,6 +2281,14 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
return false;
}
int totuv = CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV);
int *cd_uvs = BLI_array_alloca(cd_uvs, totuv);
for (int i = 0; i < totuv; i++) {
int idx = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, i);
cd_uvs[i] = bm->ldata.layers[idx].offset;
}
node->flag |= PBVH_UpdateOtherVerts;
int mat_map[MAXMAT];
@ -2354,26 +2392,28 @@ bool BKE_pbvh_bmesh_check_tris(PBVH *pbvh, PBVHNode *node)
mat_tri->eflag |= 1 << j;
}
if (!BLI_smallhash_ensure_p(&node->tribuf->vertmap, (uintptr_t)l->v, &val)) {
uintptr_t loopkey = tri_loopkey(l, mat_nr, pbvh->cd_faceset_offset, cd_uvs, totuv);
if (!BLI_smallhash_ensure_p(&node->tribuf->vertmap, loopkey, &val)) {
SculptVertRef sv = {(intptr_t)l->v};
minmax_v3v3_v3(min, max, l->v->co);
*val = POINTER_FROM_INT(node->tribuf->totvert);
pbvh_tribuf_add_vert(node->tribuf, sv);
pbvh_tribuf_add_vert(node->tribuf, sv, l);
}
tri->v[j] = (intptr_t)val[0];
tri->l[j] = (intptr_t)l;
val = NULL;
if (!BLI_smallhash_ensure_p(&mat_tribuf->vertmap, (uintptr_t)l->v, &val)) {
if (!BLI_smallhash_ensure_p(&mat_tribuf->vertmap, loopkey, &val)) {
SculptVertRef sv = {(intptr_t)l->v};
minmax_v3v3_v3(min, max, l->v->co);
*val = POINTER_FROM_INT(mat_tribuf->totvert);
pbvh_tribuf_add_vert(mat_tribuf, sv);
pbvh_tribuf_add_vert(mat_tribuf, sv, l);
}
mat_tri->v[j] = (intptr_t)val[0];

View File

@ -281,6 +281,7 @@ static void partialvis_update_bmesh(Object *ob,
if (any_changed) {
BKE_pbvh_node_mark_rebuild_draw(node);
BKE_pbvh_node_fully_hidden_set(node, !any_visible);
BKE_pbvh_node_mark_update_triangulation(node);
}
}

View File

@ -1023,6 +1023,7 @@ void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visibl
BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) {
int fset = BM_ELEM_CD_GET_INT(f, ss->cd_faceset_offset);
int node = BM_ELEM_CD_GET_INT(f, ss->cd_face_node_offset);
if (abs(fset) != face_set) {
continue;
@ -1035,6 +1036,10 @@ void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visibl
fset = -abs(fset);
}
if (node != DYNTOPO_NODE_NONE) {
BKE_pbvh_node_mark_update_triangulation(BKE_pbvh_node_from_index(ss->pbvh, node));
}
BM_ELEM_CD_SET_INT(f, ss->cd_faceset_offset, fset);
}
break;
@ -1107,6 +1112,11 @@ void SCULPT_face_sets_visibility_all_set(SculptSession *ss, bool visible)
BM_ITER_MESH (f, &iter, ss->bm, BM_FACES_OF_MESH) {
int fset = BM_ELEM_CD_GET_INT(f, ss->cd_faceset_offset);
int node = BM_ELEM_CD_GET_INT(f, ss->cd_face_node_offset);
if (node != DYNTOPO_NODE_NONE) {
BKE_pbvh_node_mark_update_triangulation(BKE_pbvh_node_from_index(ss->pbvh, node));
}
/* This can run on geometry without a face set assigned, so its ID sign can't be changed to
* modify the visibility. Force that geometry to the ID 1 to enable changing the visibility

View File

@ -1 +1,5 @@
#pragma once
typedef struct SculptDisplacer {
} SculptDisplacer;

View File

@ -102,7 +102,7 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
slide_fset = MAX2(slide_fset, bound_smooth);
if (check_fsets) {
bflag |= SCULPT_BOUNDARY_FACE_SET;
bflag |= SCULPT_BOUNDARY_FACE_SET | SCULPT_BOUNDARY_SEAM;
}
const SculptBoundaryType is_boundary = SCULPT_vertex_is_boundary(ss, vertex, bflag);
@ -124,7 +124,7 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
SculptCornerType ctype = SCULPT_CORNER_MESH | SCULPT_CORNER_SHARP;
if (check_fsets) {
ctype |= SCULPT_CORNER_FACE_SET;
ctype |= SCULPT_CORNER_FACE_SET | SCULPT_CORNER_SEAM;
}
// bool have_bmesh = ss->bm;
@ -201,7 +201,8 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
*/
bool slide = (slide_fset > 0.0f && is_boundary == SCULPT_BOUNDARY_FACE_SET) ||
bool slide = (slide_fset > 0.0f &&
(is_boundary & (SCULPT_BOUNDARY_FACE_SET | SCULPT_BOUNDARY_SEAM))) ||
bound_smooth > 0.0f;
slide = slide && !final_boundary;
@ -334,7 +335,7 @@ void SCULPT_neighbor_coords_average_interior(SculptSession *ss,
return;
}
if (c & SCULPT_CORNER_FACE_SET) {
if (c & (SCULPT_CORNER_FACE_SET | SCULPT_CORNER_SEAM)) {
corner_smooth = MAX2(slide_fset, bound_smooth);
}
else {
@ -1003,7 +1004,7 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
SculptCornerType ctype = SCULPT_CORNER_MESH | SCULPT_CORNER_SHARP;
if (check_fsets) {
ctype |= SCULPT_CORNER_FACE_SET;
ctype |= SCULPT_CORNER_FACE_SET | SCULPT_CORNER_SEAM;
}
if (weighted || ss->cache->brush->boundary_smooth_factor > 0.0f) {

View File

@ -1179,17 +1179,21 @@ static int gpu_bmesh_vert_visible_count(TableGSet *bm_unique_verts, TableGSet *b
}
/* Return the total number of visible faces */
static int gpu_bmesh_face_visible_count(TableGSet *bm_faces, int mat_nr)
static int gpu_bmesh_face_visible_count(PBVHTriBuf *tribuf, int mat_nr)
{
int totface = 0;
BMFace *f;
TGSET_ITER (f, bm_faces) {
if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN) && f->mat_nr == mat_nr) {
totface++;
for (int i = 0; i < tribuf->tottri; i++) {
PBVHTri *tri = tribuf->tris + i;
BMFace *f = (BMFace *)tri->f.i;
if (f->mat_nr != mat_nr || BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
continue;
}
totface++;
}
TGSET_ITER_END
return totface;
}
@ -1485,7 +1489,7 @@ static void GPU_pbvh_bmesh_buffers_update_flat_vcol(GPU_PBVH_Buffers *buffers,
&bm->vdata, cd_vcols, cd_vcol_layers, active_vcol_only);
/* Count visible triangles */
tottri = tribuf->tottri * 6;
tottri = gpu_bmesh_face_visible_count(tribuf, mat_nr) * 6;
totvert = tottri * 3;
if (!tottri) {
@ -1667,7 +1671,7 @@ static void GPU_pbvh_bmesh_buffers_update_indexed(GPU_PBVH_Buffers *buffers,
&bm->vdata, cd_vcols, cd_vcol_layers, active_vcol_only);
/* Count visible triangles */
tottri = tribuf->tottri;
tottri = gpu_bmesh_face_visible_count(tribuf, mat_nr);
/* Count visible vertices */
totvert = tribuf->totvert;
@ -1685,6 +1689,12 @@ static void GPU_pbvh_bmesh_buffers_update_indexed(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);
int cd_fset_offset = CustomData_get_offset(&bm->pdata, CD_SCULPT_FACE_SETS);
// int totuv = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
// int *cd_uvs = BLI_array_alloca(cd_uvs, totuv);
const int cd_uv = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
const bool have_uv = cd_uv >= 0;
bool default_face_set = true;
@ -1733,6 +1743,7 @@ static void GPU_pbvh_bmesh_buffers_update_indexed(GPU_PBVH_Buffers *buffers,
for (int i = 0; i < tribuf->totvert; i++) {
BMVert *v = (BMVert *)tribuf->verts[i].i;
BMLoop *l = (BMLoop *)tribuf->loops[i];
#ifdef QUANTIZED_PERF_TEST
float co[3];
@ -1771,6 +1782,25 @@ static void GPU_pbvh_bmesh_buffers_update_indexed(GPU_PBVH_Buffers *buffers,
cd_vcols,
cd_vcol_count);
#endif
if (!g_vbo_id.fast_mode) {
const uchar face_set_color[3] = {UCHAR_MAX, UCHAR_MAX, UCHAR_MAX};
/* Add default face sets color to avoid artifacts. */
int fset = BM_ELEM_CD_GET_INT(l->f, cd_fset_offset);
if (fset != face_sets_color_default) {
default_face_set = false;
BKE_paint_face_set_overlay_color_get(fset, face_sets_color_seed, face_set_color);
}
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.fset, i, &face_set_color);
}
if (have_uv) {
MLoopUV *mu = BM_ELEM_CD_GET_VOID_P(l, cd_uv);
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.uv, i, mu->uv);
}
}
if (!need_indexed) {
@ -1794,6 +1824,11 @@ static void GPU_pbvh_bmesh_buffers_update_indexed(GPU_PBVH_Buffers *buffers,
for (int i = 0; i < tribuf->tottri; i++) {
PBVHTri *tri = tribuf->tris + i;
BMFace *f = (BMFace *)tri->f.i;
if (f->mat_nr != mat_nr || BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
continue;
}
GPU_indexbuf_add_tri_verts(&elb, tri->v[0], tri->v[1], tri->v[2]);
#ifndef QUANTIZED_PERF_TEST
@ -1874,7 +1909,7 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
&bm->vdata, cd_vcols, cd_vcol_layers, active_vcol_only);
/* Count visible triangles */
if (buffers->smooth && !have_uv) {
if (buffers->smooth) {
GPU_pbvh_bmesh_buffers_update_indexed(buffers,
bm,
bm_faces,
@ -1900,7 +1935,7 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
bool default_face_set = true;
#ifdef DYNTOPO_DYNAMIC_TESS
tottri = tribuf->tottri;
tottri = gpu_bmesh_face_visible_count(tribuf, mat_nr);
totvert = tottri * 3;
if (!tottri) {
@ -1929,7 +1964,7 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
BMLoop **l = (BMLoop **)tri->l;
BMVert *v[3];
if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
if (f->mat_nr != mat_nr || BM_elem_flag_test(f, BM_ELEM_HIDDEN)) {
continue;
}

View File

@ -57,7 +57,6 @@
#include "BKE_callbacks.h"
#include "BKE_context.h"
#include "BKE_curvemapping_cache.h"
#include "BKE_font.h"
#include "BKE_global.h"
#include "BKE_icons.h"
#include "BKE_image.h"