Fix T94865: GPU subdiv crash switching to texpaint area

The crash is due to the fact that GPU subdivision extraction routines
for edit data (including UVs) only worked for BMesh. However, a Mesh
based version is still needed for texture painting. This adds the
missing components. This also ensures all data are properly initialized
(at least the ones revealed by the bug).
This commit is contained in:
Kévin Dietrich 2022-01-16 08:40:38 +01:00
parent 3574f2730d
commit bc66cd9868
Notes: blender-bot 2023-02-14 01:35:49 +01:00
Referenced by issue #94865, Crash when switching to texture paint workspace on models with a subdivision modifier
7 changed files with 196 additions and 69 deletions

View File

@ -848,6 +848,7 @@ static void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache *cache,
}
MeshRenderData mr;
memset(&mr, 0, sizeof(MeshRenderData));
draw_subdiv_init_mesh_render_data(subdiv_cache, &mr, ts);
mesh_render_data_update_loose_geom(&mr, mbc, MR_ITER_LEDGE | MR_ITER_LVERT, MR_DATA_LOOSE_GEOM);
@ -860,9 +861,25 @@ static void mesh_buffer_cache_create_requested_subdiv(MeshBatchCache *cache,
extractor->init_subdiv(subdiv_cache, &mr, cache, buffer, data);
if (extractor->iter_subdiv) {
for (uint i = 0; i < subdiv_cache->num_subdiv_quads; i++) {
extractor->iter_subdiv(subdiv_cache, &mr, data, i);
if (extractor->iter_subdiv_mesh || extractor->iter_subdiv_bm) {
int *subdiv_loop_poly_index = subdiv_cache->subdiv_loop_poly_index;
if (subdiv_cache->bm) {
for (uint i = 0; i < subdiv_cache->num_subdiv_quads; i++) {
/* Multiply by 4 to have the start index of the quad's loop, as subdiv_loop_poly_index is
* based on the subdivision loops. */
const int poly_origindex = subdiv_loop_poly_index[i * 4];
const BMFace *efa = bm_original_face_get(&mr, poly_origindex);
extractor->iter_subdiv_bm(subdiv_cache, &mr, data, i, efa);
}
}
else {
for (uint i = 0; i < subdiv_cache->num_subdiv_quads; i++) {
/* Multiply by 4 to have the start index of the quad's loop, as subdiv_loop_poly_index is
* based on the subdivision loops. */
const int poly_origindex = subdiv_loop_poly_index[i * 4];
const MPoly *mp = &mr.mpoly[poly_origindex];
extractor->iter_subdiv_mesh(subdiv_cache, &mr, data, i, mp);
}
}
}

View File

@ -1676,6 +1676,10 @@ void draw_subdiv_init_mesh_render_data(DRWSubdivCache *cache,
mr->poly_len = mesh->totpoly;
mr->loop_len = mesh->totloop;
mr->extract_type = MR_EXTRACT_MESH;
mr->toolsettings = toolsettings;
mr->v_origindex = static_cast<int *>(CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX));
mr->e_origindex = static_cast<int *>(CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX));
mr->p_origindex = static_cast<int *>(CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX));
/* MeshRenderData is only used for generating edit mode data here. */
if (!cache->bm) {
@ -1686,7 +1690,6 @@ void draw_subdiv_init_mesh_render_data(DRWSubdivCache *cache,
BM_mesh_elem_table_ensure(bm, BM_EDGE | BM_FACE | BM_VERT);
mr->bm = bm;
mr->toolsettings = toolsettings;
mr->eed_act = BM_mesh_active_edge_get(bm);
mr->efa_act = BM_mesh_active_face_get(bm, false, true);
mr->eve_act = BM_mesh_active_vert_get(bm);
@ -1696,9 +1699,6 @@ void draw_subdiv_init_mesh_render_data(DRWSubdivCache *cache,
mr->freestyle_edge_ofs = CustomData_get_offset(&bm->edata, CD_FREESTYLE_EDGE);
mr->freestyle_face_ofs = CustomData_get_offset(&bm->pdata, CD_FREESTYLE_FACE);
#endif
mr->v_origindex = static_cast<int *>(CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX));
mr->e_origindex = static_cast<int *>(CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX));
mr->p_origindex = static_cast<int *>(CustomData_get_layer(&mr->me->pdata, CD_ORIGINDEX));
}
/**

View File

@ -223,10 +223,16 @@ typedef void(ExtractInitSubdivFn)(const struct DRWSubdivCache *subdiv_cache,
struct MeshBatchCache *cache,
void *buf,
void *data);
typedef void(ExtractIterSubdivFn)(const struct DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *data,
uint subdiv_quad_index);
typedef void(ExtractIterSubdivBMeshFn)(const struct DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *data,
uint subdiv_quad_index,
const BMFace *coarse_quad);
typedef void(ExtractIterSubdivMeshFn)(const struct DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *data,
uint subdiv_quad_index,
const MPoly *coarse_quad);
typedef void(ExtractFinishSubdivFn)(const struct DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
struct MeshBatchCache *cache,
@ -251,7 +257,8 @@ typedef struct MeshExtract {
ExtractFinishFn *finish;
/** Executed on main thread for subdivision evaluation. */
ExtractInitSubdivFn *init_subdiv;
ExtractIterSubdivFn *iter_subdiv;
ExtractIterSubdivBMeshFn *iter_subdiv_bm;
ExtractIterSubdivMeshFn *iter_subdiv_mesh;
ExtractFinishSubdivFn *finish_subdiv;
/** Used to request common data. */
eMRDataType data_type;

View File

@ -110,28 +110,49 @@ static void extract_edituv_tris_init_subdiv(const DRWSubdivCache *subdiv_cache,
data->sync_selection = (mr->toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
}
static void extract_edituv_tris_iter_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index)
static void extract_edituv_tris_iter_subdiv_bm(const DRWSubdivCache *UNUSED(subdiv_cache),
const MeshRenderData *UNUSED(mr),
void *_data,
uint subdiv_quad_index,
const BMFace *coarse_quad)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
int *subdiv_loop_poly_index = subdiv_cache->subdiv_loop_poly_index;
const uint loop_idx = subdiv_quad_index * 4;
const int poly_origindex = subdiv_loop_poly_index[loop_idx];
BMFace *efa = bm_original_face_get(mr, poly_origindex);
edituv_tri_add(data,
BM_elem_flag_test(efa, BM_ELEM_HIDDEN) != 0,
BM_elem_flag_test(efa, BM_ELEM_SELECT) != 0,
BM_elem_flag_test(coarse_quad, BM_ELEM_HIDDEN) != 0,
BM_elem_flag_test(coarse_quad, BM_ELEM_SELECT) != 0,
loop_idx,
loop_idx + 1,
loop_idx + 2);
edituv_tri_add(data,
BM_elem_flag_test(efa, BM_ELEM_HIDDEN) != 0,
BM_elem_flag_test(efa, BM_ELEM_SELECT) != 0,
BM_elem_flag_test(coarse_quad, BM_ELEM_HIDDEN) != 0,
BM_elem_flag_test(coarse_quad, BM_ELEM_SELECT) != 0,
loop_idx,
loop_idx + 2,
loop_idx + 3);
}
static void extract_edituv_tris_iter_subdiv_mesh(const DRWSubdivCache *UNUSED(subdiv_cache),
const MeshRenderData *UNUSED(mr),
void *_data,
uint subdiv_quad_index,
const MPoly *coarse_quad)
{
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);
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);
@ -156,7 +177,8 @@ constexpr MeshExtract create_extractor_edituv_tris()
extractor.iter_looptri_mesh = extract_edituv_tris_iter_looptri_mesh;
extractor.finish = extract_edituv_tris_finish;
extractor.init_subdiv = extract_edituv_tris_init_subdiv;
extractor.iter_subdiv = extract_edituv_tris_iter_subdiv;
extractor.iter_subdiv_bm = extract_edituv_tris_iter_subdiv_bm;
extractor.iter_subdiv_mesh = extract_edituv_tris_iter_subdiv_mesh;
extractor.finish_subdiv = extract_edituv_tris_finish_subdiv;
extractor.data_type = MR_DATA_NONE;
extractor.data_size = sizeof(MeshExtract_EditUvElem_Data);
@ -253,28 +275,49 @@ static void extract_edituv_lines_init_subdiv(const DRWSubdivCache *subdiv_cache,
data->sync_selection = (mr->toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
}
static void extract_edituv_lines_iter_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index)
static void extract_edituv_lines_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const BMFace *coarse_poly)
{
MeshExtract_EditUvElem_Data *data = static_cast<MeshExtract_EditUvElem_Data *>(_data);
int *subdiv_loop_poly_index = subdiv_cache->subdiv_loop_poly_index;
int *subdiv_loop_edge_index = (int *)GPU_vertbuf_get_data(subdiv_cache->edges_orig_index);
uint start_loop_idx = subdiv_quad_index * 4;
uint end_loop_idx = (subdiv_quad_index + 1) * 4;
const int poly_origindex = subdiv_loop_poly_index[start_loop_idx];
BMFace *efa = bm_original_face_get(mr, poly_origindex);
for (uint loop_idx = start_loop_idx; loop_idx < end_loop_idx; loop_idx++) {
const int edge_origindex = subdiv_loop_edge_index[loop_idx];
const bool real_edge = (edge_origindex != -1 &&
mr->e_origindex[edge_origindex] != ORIGINDEX_NONE);
(mr->e_origindex == nullptr ||
mr->e_origindex[edge_origindex] != ORIGINDEX_NONE));
edituv_edge_add(data,
BM_elem_flag_test_bool(efa, BM_ELEM_HIDDEN) != 0 || !real_edge,
BM_elem_flag_test_bool(efa, BM_ELEM_SELECT) != 0,
BM_elem_flag_test_bool(coarse_poly, BM_ELEM_HIDDEN) != 0 || !real_edge,
BM_elem_flag_test_bool(coarse_poly, BM_ELEM_SELECT) != 0,
loop_idx,
(loop_idx + 1 == end_loop_idx) ? start_loop_idx : (loop_idx + 1));
}
}
static void extract_edituv_lines_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly *coarse_poly)
{
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);
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++) {
const int edge_origindex = subdiv_loop_edge_index[loop_idx];
const bool real_edge = (edge_origindex != -1 &&
(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,
loop_idx,
(loop_idx + 1 == end_loop_idx) ? start_loop_idx : (loop_idx + 1));
}
@ -299,7 +342,8 @@ constexpr MeshExtract create_extractor_edituv_lines()
extractor.iter_poly_mesh = extract_edituv_lines_iter_poly_mesh;
extractor.finish = extract_edituv_lines_finish;
extractor.init_subdiv = extract_edituv_lines_init_subdiv;
extractor.iter_subdiv = extract_edituv_lines_iter_subdiv;
extractor.iter_subdiv_bm = extract_edituv_lines_iter_subdiv_bm;
extractor.iter_subdiv_mesh = extract_edituv_lines_iter_subdiv_mesh;
extractor.finish_subdiv = extract_edituv_lines_finish_subdiv;
extractor.data_type = MR_DATA_NONE;
extractor.data_size = sizeof(MeshExtract_EditUvElem_Data);
@ -390,28 +434,48 @@ static void extract_edituv_points_init_subdiv(const DRWSubdivCache *subdiv_cache
data->sync_selection = (mr->toolsettings->uv_flag & UV_SYNC_SELECTION) != 0;
}
static void extract_edituv_points_iter_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index)
static void extract_edituv_points_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const BMFace *coarse_quad)
{
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);
int *subdiv_loop_poly_index = subdiv_cache->subdiv_loop_poly_index;
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 int poly_origindex = subdiv_loop_poly_index[i];
BMFace *efa = bm_original_face_get(mr, poly_origindex);
const bool real_vert = (mr->extract_type == MR_EXTRACT_MAPPED && (mr->v_origindex) &&
vert_origindex != -1 &&
mr->v_origindex[vert_origindex] != ORIGINDEX_NONE);
edituv_point_add(data,
(BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || !real_vert,
BM_elem_flag_test(efa, BM_ELEM_SELECT) != 0,
(BM_elem_flag_test(coarse_quad, BM_ELEM_HIDDEN)) || !real_vert,
BM_elem_flag_test(coarse_quad, BM_ELEM_SELECT) != 0,
i);
}
}
static void extract_edituv_points_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly *coarse_quad)
{
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);
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->extract_type == MR_EXTRACT_MAPPED && (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);
}
}
@ -435,7 +499,8 @@ constexpr MeshExtract create_extractor_edituv_points()
extractor.iter_poly_mesh = extract_edituv_points_iter_poly_mesh;
extractor.finish = extract_edituv_points_finish;
extractor.init_subdiv = extract_edituv_points_init_subdiv;
extractor.iter_subdiv = extract_edituv_points_iter_subdiv;
extractor.iter_subdiv_bm = extract_edituv_points_iter_subdiv_bm;
extractor.iter_subdiv_mesh = extract_edituv_points_iter_subdiv_mesh;
extractor.finish_subdiv = extract_edituv_points_finish_subdiv;
extractor.data_type = MR_DATA_NONE;
extractor.data_size = sizeof(MeshExtract_EditUvElem_Data);

View File

@ -218,6 +218,24 @@ static void extract_lines_adjacency_iter_subdiv(const DRWSubdivCache *subdiv_cac
lines_adjacency_triangle(v0, v2, v3, l0, l2, l3, data);
}
static void extract_lines_adjacency_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const BMFace *UNUSED(coarse_quad))
{
extract_lines_adjacency_iter_subdiv(subdiv_cache, mr, _data, subdiv_quad_index);
}
static void extract_lines_adjacency_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly *UNUSED(coarse_quad))
{
extract_lines_adjacency_iter_subdiv(subdiv_cache, mr, _data, subdiv_quad_index);
}
static void extract_lines_adjacency_finish_subdiv(const DRWSubdivCache *UNUSED(subdiv_cache),
const MeshRenderData *mr,
struct MeshBatchCache *cache,
@ -237,7 +255,8 @@ constexpr MeshExtract create_extractor_lines_adjacency()
extractor.iter_looptri_mesh = extract_lines_adjacency_iter_looptri_mesh;
extractor.finish = extract_lines_adjacency_finish;
extractor.init_subdiv = extract_lines_adjacency_init_subdiv;
extractor.iter_subdiv = extract_lines_adjacency_iter_subdiv;
extractor.iter_subdiv_bm = extract_lines_adjacency_iter_subdiv_bm;
extractor.iter_subdiv_mesh = extract_lines_adjacency_iter_subdiv_mesh;
extractor.finish_subdiv = extract_lines_adjacency_finish_subdiv;
extractor.data_type = MR_DATA_NONE;
extractor.data_size = sizeof(MeshExtract_LineAdjacency_Data);

View File

@ -261,22 +261,21 @@ static void extract_edit_data_init_subdiv(const DRWSubdivCache *subdiv_cache,
*(EditLoopData **)data = vbo_data;
}
static void extract_edit_data_iter_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index)
static void extract_edit_data_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const BMFace *coarse_quad)
{
EditLoopData *vbo_data = *(EditLoopData **)_data;
int *subdiv_loop_vert_index = (int *)GPU_vertbuf_get_data(subdiv_cache->verts_orig_index);
int *subdiv_loop_edge_index = (int *)GPU_vertbuf_get_data(subdiv_cache->edges_orig_index);
int *subdiv_loop_poly_index = subdiv_cache->subdiv_loop_poly_index;
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 int edge_origindex = subdiv_loop_edge_index[i];
const int poly_origindex = subdiv_loop_poly_index[i];
EditLoopData *edit_loop_data = &vbo_data[i];
memset(edit_loop_data, 0, sizeof(EditLoopData));
@ -295,12 +294,22 @@ static void extract_edit_data_iter_subdiv(const DRWSubdivCache *subdiv_cache,
}
}
BMFace *efa = bm_original_face_get(mr, poly_origindex);
/* The -1 parameter is for edit_uvs, which we don't do here. */
mesh_render_data_face_flag(mr, efa, -1, edit_loop_data);
mesh_render_data_face_flag(mr, coarse_quad, -1, edit_loop_data);
}
}
static void extract_edit_data_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly *coarse_quad)
{
const int coarse_quad_index = static_cast<int>(coarse_quad - mr->mpoly);
BMFace *coarse_quad_bm = bm_original_face_get(mr, coarse_quad_index);
extract_edit_data_iter_subdiv_bm(subdiv_cache, mr, _data, subdiv_quad_index, coarse_quad_bm);
}
static void extract_edit_data_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
const MeshExtractLooseGeom *loose_geom,
@ -336,7 +345,8 @@ constexpr MeshExtract create_extractor_edit_data()
extractor.iter_lvert_bm = extract_edit_data_iter_lvert_bm;
extractor.iter_lvert_mesh = extract_edit_data_iter_lvert_mesh;
extractor.init_subdiv = extract_edit_data_init_subdiv;
extractor.iter_subdiv = extract_edit_data_iter_subdiv;
extractor.iter_subdiv_bm = extract_edit_data_iter_subdiv_bm;
extractor.iter_subdiv_mesh = extract_edit_data_iter_subdiv_mesh;
extractor.iter_loose_geom_subdiv = extract_edit_data_loose_geom_subdiv;
extractor.data_type = MR_DATA_NONE;
extractor.data_size = sizeof(EditLoopData *);

View File

@ -139,38 +139,46 @@ static void extract_edituv_data_init_subdiv(const DRWSubdivCache *subdiv_cache,
extract_edituv_data_init_common(mr, vbo, data, subdiv_cache->num_subdiv_loops);
}
static void extract_edituv_data_iter_subdiv(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index)
static void extract_edituv_data_iter_subdiv_bm(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const BMFace *coarse_quad)
{
MeshExtract_EditUVData_Data *data = static_cast<MeshExtract_EditUVData_Data *>(_data);
int *subdiv_loop_vert_index = (int *)GPU_vertbuf_get_data(subdiv_cache->verts_orig_index);
int *subdiv_loop_edge_index = (int *)GPU_vertbuf_get_data(subdiv_cache->edges_orig_index);
int *subdiv_loop_poly_index = subdiv_cache->subdiv_loop_poly_index;
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 int edge_origindex = subdiv_loop_edge_index[i];
const int poly_origindex = subdiv_loop_poly_index[i];
EditLoopData *edit_loop_data = &data->vbo_data[i];
memset(edit_loop_data, 0, sizeof(EditLoopData));
BMFace *efa = bm_original_face_get(mr, poly_origindex);
if (vert_origindex != -1 && edge_origindex != -1) {
BMEdge *eed = bm_original_edge_get(mr, edge_origindex);
/* Loop on an edge endpoint. */
BMLoop *l = BM_face_edge_share_loop(efa, eed);
BMLoop *l = BM_face_edge_share_loop(const_cast<BMFace *>(coarse_quad), eed);
mesh_render_data_loop_flag(mr, l, data->cd_ofs, edit_loop_data);
mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, edit_loop_data);
}
}
}
static void extract_edituv_data_iter_subdiv_mesh(const DRWSubdivCache *subdiv_cache,
const MeshRenderData *mr,
void *_data,
uint subdiv_quad_index,
const MPoly *coarse_quad)
{
const int coarse_quad_index = static_cast<int>(coarse_quad - mr->mpoly);
BMFace *coarse_quad_bm = bm_original_face_get(mr, coarse_quad_index);
extract_edituv_data_iter_subdiv_bm(subdiv_cache, mr, _data, subdiv_quad_index, coarse_quad_bm);
}
constexpr MeshExtract create_extractor_edituv_data()
{
MeshExtract extractor = {nullptr};
@ -178,7 +186,8 @@ constexpr MeshExtract create_extractor_edituv_data()
extractor.iter_poly_bm = extract_edituv_data_iter_poly_bm;
extractor.iter_poly_mesh = extract_edituv_data_iter_poly_mesh;
extractor.init_subdiv = extract_edituv_data_init_subdiv;
extractor.iter_subdiv = extract_edituv_data_iter_subdiv;
extractor.iter_subdiv_bm = extract_edituv_data_iter_subdiv_bm;
extractor.iter_subdiv_mesh = extract_edituv_data_iter_subdiv_mesh;
extractor.data_type = MR_DATA_NONE;
extractor.data_size = sizeof(MeshExtract_EditUVData_Data);
extractor.use_threading = true;