Fix T98773: GPU subdivision issues with UV editor display

This fixes missing selection updates in UV editor, both with GPU subdivision
and with the Modified Edges display option for modifiers in general.

It also fixes the UV editor incorrectly showing the cage mesh with deformed
coordinates. These are not yet supported by the UV selection system.

Changes:

* Always read selection state from the editmesh when building batches. The
  flags in the evaluated mesh can be outdated as selection bypasses depsgraph
  evaluation for performance, and instead may just clear the batches.
* runtime.is_original is only valid for the bmesh wrapper. The check for
  building the UV cage should only use that if the mesh is a bmesh wrapper.
* Don't create cage batches for objects whose mesh is in edit mode, but that
  are not themselves in edit mode, there is no need.

Differential Revision: https://developer.blender.org/D15658
This commit is contained in:
Brecht Van Lommel 2022-08-16 16:00:50 +02:00
parent a1b8013cc3
commit 8cf52e8226
Notes: blender-bot 2023-02-14 00:10:08 +01:00
Referenced by commit d9ea72291f, Fix T100842: Display Texture Paint UVs option in UV editor not working
Referenced by issue #100842, Regression: Missing UVs in imaged editor when in texture paint mode
Referenced by issue #98773,   GPU Subdivision breaks auto selection in UV edit mode
2 changed files with 50 additions and 45 deletions

View File

@ -1508,12 +1508,13 @@ void DRW_mesh_batch_cache_create_requested(struct TaskGraph *task_graph,
cache->batch_ready |= batch_requested;
bool do_cage = false, do_uvcage = false;
if (is_editmode) {
if (is_editmode && is_mode_active) {
Mesh *editmesh_eval_final = BKE_object_get_editmesh_eval_final(ob);
Mesh *editmesh_eval_cage = BKE_object_get_editmesh_eval_cage(ob);
do_cage = editmesh_eval_final != editmesh_eval_cage;
do_uvcage = !editmesh_eval_final->runtime.is_original;
do_uvcage = !(editmesh_eval_final->runtime.is_original &&
editmesh_eval_final->runtime.wrapper_type == ME_WRAPPER_TYPE_BMESH);
}
const bool do_subdivision = BKE_subsurf_modifier_has_gpu_subdiv(me);

View File

@ -59,13 +59,11 @@ static void extract_edituv_tris_iter_looptri_mesh(const MeshRenderData *mr,
void *_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
const MPoly *mp = &mr->mpoly[mlt->poly];
edituv_tri_add(data,
(mp->flag & ME_HIDE) != 0,
(mp->flag & ME_FACE_SEL) != 0,
mlt->tri[0],
mlt->tri[1],
mlt->tri[2]);
const BMFace *efa = bm_original_face_get(mr, mlt->poly);
const bool mp_hidden = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_HIDDEN) : true;
const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
edituv_tri_add(data, mp_hidden, mp_select, mlt->tri[0], mlt->tri[1], mlt->tri[2]);
}
static void extract_edituv_tris_finish(const MeshRenderData *UNUSED(mr),
@ -117,7 +115,7 @@ static void extract_edituv_tris_iter_subdiv_bm(const DRWSubdivCache *UNUSED(subd
}
static void extract_edituv_tris_iter_subdiv_mesh(const DRWSubdivCache *UNUSED(subdiv_cache),
const MeshRenderData *UNUSED(mr),
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly *coarse_quad)
@ -125,19 +123,12 @@ static void extract_edituv_tris_iter_subdiv_mesh(const DRWSubdivCache *UNUSED(su
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
const uint loop_idx = subdiv_quad_index * 4;
edituv_tri_add(data,
(coarse_quad->flag & ME_HIDE) != 0,
(coarse_quad->flag & ME_FACE_SEL) != 0,
loop_idx,
loop_idx + 1,
loop_idx + 2);
const BMFace *efa = bm_original_face_get(mr, coarse_quad - mr->mpoly);
const bool mp_hidden = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_HIDDEN) : true;
const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
edituv_tri_add(data,
(coarse_quad->flag & ME_HIDE) != 0,
(coarse_quad->flag & ME_FACE_SEL) != 0,
loop_idx,
loop_idx + 2,
loop_idx + 3);
edituv_tri_add(data, mp_hidden, mp_select, loop_idx, loop_idx + 1, loop_idx + 2);
edituv_tri_add(data, mp_hidden, mp_select, loop_idx, loop_idx + 2, loop_idx + 3);
}
static void extract_edituv_tris_finish_subdiv(const struct DRWSubdivCache *UNUSED(subdiv_cache),
@ -214,12 +205,17 @@ static void extract_edituv_lines_iter_poly_bm(const MeshRenderData *UNUSED(mr),
static void extract_edituv_lines_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *mp,
const int UNUSED(mp_index),
const int mp_index,
void *_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
const BMFace *efa = bm_original_face_get(mr, mp_index);
const bool mp_hidden = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_HIDDEN) : true;
const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
@ -227,11 +223,7 @@ static void extract_edituv_lines_iter_poly_mesh(const MeshRenderData *mr,
const int ml_index_next = (ml_index == ml_index_last) ? mp->loopstart : (ml_index + 1);
const bool real_edge = (mr->e_origindex == nullptr ||
mr->e_origindex[ml->e] != ORIGINDEX_NONE);
edituv_edge_add(data,
(mp->flag & ME_HIDE) != 0 || !real_edge,
(mp->flag & ME_FACE_SEL) != 0,
ml_index,
ml_index_next);
edituv_edge_add(data, mp_hidden || !real_edge, mp_select, ml_index, ml_index_next);
}
}
@ -266,6 +258,9 @@ static void extract_edituv_lines_iter_subdiv_bm(const DRWSubdivCache *subdiv_cac
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
int *subdiv_loop_edge_index = (int *)GPU_vertbuf_get_data(subdiv_cache->edges_orig_index);
const bool mp_hidden = BM_elem_flag_test_bool(coarse_poly, BM_ELEM_HIDDEN);
const bool mp_select = BM_elem_flag_test_bool(coarse_poly, BM_ELEM_SELECT);
uint start_loop_idx = subdiv_quad_index * 4;
uint end_loop_idx = (subdiv_quad_index + 1) * 4;
for (uint loop_idx = start_loop_idx; loop_idx < end_loop_idx; loop_idx++) {
@ -274,8 +269,8 @@ static void extract_edituv_lines_iter_subdiv_bm(const DRWSubdivCache *subdiv_cac
(mr->e_origindex == nullptr ||
mr->e_origindex[edge_origindex] != ORIGINDEX_NONE));
edituv_edge_add(data,
BM_elem_flag_test_bool(coarse_poly, BM_ELEM_HIDDEN) != 0 || !real_edge,
BM_elem_flag_test_bool(coarse_poly, BM_ELEM_SELECT) != 0,
mp_hidden || !real_edge,
mp_select,
loop_idx,
(loop_idx + 1 == end_loop_idx) ? start_loop_idx : (loop_idx + 1));
}
@ -290,6 +285,10 @@ static void extract_edituv_lines_iter_subdiv_mesh(const DRWSubdivCache *subdiv_c
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
int *subdiv_loop_edge_index = (int *)GPU_vertbuf_get_data(subdiv_cache->edges_orig_index);
const BMFace *efa = bm_original_face_get(mr, coarse_poly - mr->mpoly);
const bool mp_hidden = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_HIDDEN) : true;
const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
uint start_loop_idx = subdiv_quad_index * 4;
uint end_loop_idx = (subdiv_quad_index + 1) * 4;
for (uint loop_idx = start_loop_idx; loop_idx < end_loop_idx; loop_idx++) {
@ -298,8 +297,8 @@ static void extract_edituv_lines_iter_subdiv_mesh(const DRWSubdivCache *subdiv_c
(mr->e_origindex == nullptr ||
mr->e_origindex[edge_origindex] != ORIGINDEX_NONE));
edituv_edge_add(data,
(coarse_poly->flag & ME_HIDE) != 0 || !real_edge,
(coarse_poly->flag & ME_FACE_SEL) != 0,
mp_hidden || !real_edge,
mp_select,
loop_idx,
(loop_idx + 1 == end_loop_idx) ? start_loop_idx : (loop_idx + 1));
}
@ -378,18 +377,22 @@ static void extract_edituv_points_iter_poly_bm(const MeshRenderData *UNUSED(mr),
static void extract_edituv_points_iter_poly_mesh(const MeshRenderData *mr,
const MPoly *mp,
const int UNUSED(mp_index),
const int mp_index,
void *_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
const BMFace *efa = bm_original_face_get(mr, mp_index);
const bool mp_hidden = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_HIDDEN) : true;
const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
const bool real_vert = !mr->v_origindex || mr->v_origindex[ml->v] != ORIGINDEX_NONE;
edituv_point_add(
data, ((mp->flag & ME_HIDE) != 0) || !real_vert, (mp->flag & ME_FACE_SEL) != 0, ml_index);
edituv_point_add(data, mp_hidden || !real_vert, mp_select, ml_index);
}
}
@ -444,16 +447,17 @@ static void extract_edituv_points_iter_subdiv_mesh(const DRWSubdivCache *subdiv_
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
int *subdiv_loop_vert_index = (int *)GPU_vertbuf_get_data(subdiv_cache->verts_orig_index);
const BMFace *efa = bm_original_face_get(mr, coarse_quad - mr->mpoly);
const bool mp_hidden = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_HIDDEN) : true;
const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
uint start_loop_idx = subdiv_quad_index * 4;
uint end_loop_idx = (subdiv_quad_index + 1) * 4;
for (uint i = start_loop_idx; i < end_loop_idx; i++) {
const int vert_origindex = subdiv_loop_vert_index[i];
const bool real_vert = !mr->v_origindex || (vert_origindex != -1 &&
mr->v_origindex[vert_origindex] != ORIGINDEX_NONE);
edituv_point_add(data,
((coarse_quad->flag & ME_HIDE) != 0) || !real_vert,
(coarse_quad->flag & ME_FACE_SEL) != 0,
i);
edituv_point_add(data, mp_hidden || !real_vert, mp_select, i);
}
}
@ -533,6 +537,10 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr,
void *_data)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
const BMFace *efa = bm_original_face_get(mr, mp_index);
const bool mp_hidden = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_HIDDEN) : true;
const bool mp_select = (efa) ? BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) : false;
if (mr->use_subsurf_fdots) {
const BLI_bitmap *facedot_tags = mr->me->runtime.subsurf_face_dot_tags;
@ -543,16 +551,12 @@ static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr,
const bool real_fdot = !mr->p_origindex || (mr->p_origindex[mp_index] != ORIGINDEX_NONE);
const bool subd_fdot = BLI_BITMAP_TEST(facedot_tags, ml->v);
edituv_facedot_add(data,
((mp->flag & ME_HIDE) != 0) || !real_fdot || !subd_fdot,
(mp->flag & ME_FACE_SEL) != 0,
mp_index);
edituv_facedot_add(data, mp_hidden || !real_fdot || !subd_fdot, mp_select, mp_index);
}
}
else {
const bool real_fdot = !mr->p_origindex || (mr->p_origindex[mp_index] != ORIGINDEX_NONE);
edituv_facedot_add(
data, ((mp->flag & ME_HIDE) != 0) || !real_fdot, (mp->flag & ME_FACE_SEL) != 0, mp_index);
edituv_facedot_add(data, mp_hidden || !real_fdot, mp_select, mp_index);
}
}