From d885b1141c7cdf8c75ec7e1983546c2dd9da1004 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 1 Jul 2020 00:13:39 +1000 Subject: DRW: optimize mesh data extraction Change extraction callbacks to take index ranges instead of calling them for each mesh element (poly, loop, vert & edge). This gives a minor overall performance gain in my tests, ~5% on average. Details: - Use typed parameter structs and macros for looping over elements. Without this, changes to these callbacks is time consuming as changes need to be made in many places. - Avoid iterating over polygon-loops when iterating over polygons is sufficient. - Simplify logic to access adjacent loops for faster line extraction. - Rename 'loop' iterators to 'poly' (as they take polygon ranges) the iterator callbacks can operator on either polygon or loop data. - Use term 'last' for the last index (inclusive), use 'end' when this value (not inclusive). --- source/blender/draw/intern/draw_cache_extract.h | 2 +- .../blender/draw/intern/draw_cache_extract_mesh.c | 2719 ++++++++++++-------- 2 files changed, 1636 insertions(+), 1085 deletions(-) diff --git a/source/blender/draw/intern/draw_cache_extract.h b/source/blender/draw/intern/draw_cache_extract.h index 0b1f625dc2c..302f9a0d3a8 100644 --- a/source/blender/draw/intern/draw_cache_extract.h +++ b/source/blender/draw/intern/draw_cache_extract.h @@ -63,7 +63,7 @@ typedef struct DRW_MeshCDMask { typedef enum eMRIterType { MR_ITER_LOOPTRI = 1 << 0, - MR_ITER_LOOP = 1 << 1, + MR_ITER_POLY = 1 << 1, MR_ITER_LEDGE = 1 << 2, MR_ITER_LVERT = 1 << 3, } eMRIterType; diff --git a/source/blender/draw/intern/draw_cache_extract_mesh.c b/source/blender/draw/intern/draw_cache_extract_mesh.c index f1a7ab8c9d8..c92722fad7e 100644 --- a/source/blender/draw/intern/draw_cache_extract_mesh.c +++ b/source/blender/draw/intern/draw_cache_extract_mesh.c @@ -148,14 +148,14 @@ static void mesh_render_data_update_loose_geom(MeshRenderData *mr, BLI_bitmap *lvert_map = BLI_BITMAP_NEW(mr->vert_len, __func__); mr->ledges = MEM_mallocN(mr->edge_len * sizeof(int), __func__); - const MEdge *medge = mr->medge; - for (int e = 0; e < mr->edge_len; e++, medge++) { - if (medge->flag & ME_LOOSEEDGE) { - mr->ledges[mr->edge_loose_len++] = e; + const MEdge *med = mr->medge; + for (int med_index = 0; med_index < mr->edge_len; med_index++, med++) { + if (med->flag & ME_LOOSEEDGE) { + mr->ledges[mr->edge_loose_len++] = med_index; } /* Tag verts as not loose. */ - BLI_BITMAP_ENABLE(lvert_map, medge->v1); - BLI_BITMAP_ENABLE(lvert_map, medge->v2); + BLI_BITMAP_ENABLE(lvert_map, med->v1); + BLI_BITMAP_ENABLE(lvert_map, med->v2); } if (mr->edge_loose_len < mr->edge_len) { mr->ledges = MEM_reallocN(mr->ledges, mr->edge_loose_len * sizeof(*mr->ledges)); @@ -173,7 +173,7 @@ static void mesh_render_data_update_loose_geom(MeshRenderData *mr, MEM_freeN(lvert_map); - mr->loop_loose_len = mr->vert_loose_len + mr->edge_loose_len * 2; + mr->loop_loose_len = mr->vert_loose_len + (mr->edge_loose_len * 2); } } else { @@ -297,7 +297,7 @@ static void mesh_render_data_update_normals(MeshRenderData *mr, } mr->loop_normals = MEM_mallocN(sizeof(*mr->loop_normals) * mr->loop_len, __func__); - int clnors_offset = CustomData_get_offset(&mr->bm->ldata, CD_CUSTOMLOOPNORMAL); + const int clnors_offset = CustomData_get_offset(&mr->bm->ldata, CD_CUSTOMLOOPNORMAL); BM_loops_calc_normal_vcos(mr->bm, vert_coords, vert_normals, @@ -507,45 +507,254 @@ BLI_INLINE const float *bm_face_no_get(const MeshRenderData *mr, const BMFace *e /** \} */ /* ---------------------------------------------------------------------- */ -/** \name Mesh Elements Extract Iter +/** \name Mesh Elements Extract: Loop Triangles * \{ */ -typedef void *(ExtractInitFn)(const MeshRenderData *mr, void *buffer); - +typedef struct ExtractTriBMesh_Params { + BMLoop *(*looptris)[3]; + int tri_range[2]; +} ExtractTriBMesh_Params; typedef void(ExtractTriBMeshFn)(const MeshRenderData *mr, - int tri_index, - BMLoop **ltri, + const ExtractTriBMesh_Params *params, void *data); + +#define EXTRACT_TRIS_LOOPTRI_FOREACH_BM_BEGIN(elem_tri, index_tri, params) \ + CHECK_TYPE(params, const ExtractTriBMesh_Params *); \ + { \ + const int _tri_index_end = (params)->tri_range[1]; \ + BMLoop **elem_tri = (params)->looptris[(params)->tri_range[0]]; \ + for (int index_tri = (params)->tri_range[0]; index_tri < _tri_index_end; \ + index_tri += 1, elem_tri += 3) +#define EXTRACT_TRIS_LOOPTRI_FOREACH_BM_END } + +typedef struct ExtractTriMesh_Params { + const MLoopTri *mlooptri; + int tri_range[2]; +} ExtractTriMesh_Params; typedef void(ExtractTriMeshFn)(const MeshRenderData *mr, - int tri_index, - const MLoopTri *mlt, + const ExtractTriMesh_Params *params, void *data); -typedef void(ExtractLoopBMeshFn)(const MeshRenderData *mr, int loop_index, BMLoop *el, void *data); -typedef void(ExtractLoopMeshFn)(const MeshRenderData *mr, - int loop_index, - const MLoop *mloop, - int poly_index, - const MPoly *mpoly, +#define EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_BEGIN(elem_tri, index_tri, params) \ + CHECK_TYPE(params, const ExtractTriMesh_Params *); \ + { \ + const int _tri_index_end = (params)->tri_range[1]; \ + const MLoopTri *elem_tri = &(params)->mlooptri[(params)->tri_range[0]]; \ + for (int index_tri = (params)->tri_range[0]; index_tri < _tri_index_end; \ + index_tri += 1, elem_tri += 1) +#define EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_END } + +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Mesh Elements Extract: Polygons, Loops + * \{ */ + +typedef struct ExtractPolyBMesh_Params { + BMLoop *(*looptris)[3]; + int poly_range[2]; +} ExtractPolyBMesh_Params; +typedef void(ExtractPolyBMeshFn)(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *data); + +#define EXTRACT_POLY_FOREACH_BM_BEGIN(elem_poly, index_poly, params, mr) \ + CHECK_TYPE(params, const ExtractPolyBMesh_Params *); \ + { \ + BLI_assert((mr->bm->elem_table_dirty & BM_FACE) == 0); \ + BMFace **_ftable = mr->bm->ftable; \ + const int _poly_index_end = (params)->poly_range[1]; \ + for (int index_poly = (params)->poly_range[0]; index_poly < _poly_index_end; \ + index_poly += 1) { \ + BMFace *elem_poly = _ftable[index_poly]; \ + (void)elem_poly; + +#define EXTRACT_POLY_FOREACH_BM_END \ + } \ + } + +/* Iterate over polygon and loop. */ +#define EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(elem_loop, index_loop, params, mr) \ + CHECK_TYPE(params, const ExtractPolyBMesh_Params *); \ + { \ + BLI_assert((mr->bm->elem_table_dirty & BM_FACE) == 0); \ + BMFace **_ftable = mr->bm->ftable; \ + const int _poly_index_end = (params)->poly_range[1]; \ + for (int index_poly = (params)->poly_range[0]; index_poly < _poly_index_end; \ + index_poly += 1) { \ + BMFace *elem_face = _ftable[index_poly]; \ + BMLoop *elem_loop, *l_first; \ + elem_loop = l_first = BM_FACE_FIRST_LOOP(elem_face); \ + do { \ + const int index_loop = BM_elem_index_get(elem_loop); \ + (void)index_loop; /* Quiet warning when unused. */ + +#define EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(elem_loop) \ + } \ + while ((elem_loop = elem_loop->next) != l_first) \ + ; \ + } \ + } + +typedef struct ExtractPolyMesh_Params { + int poly_range[2]; +} ExtractPolyMesh_Params; +typedef void(ExtractPolyMeshFn)(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, void *data); +#define EXTRACT_POLY_FOREACH_MESH_BEGIN(elem_poly, index_poly, params, mr) \ + CHECK_TYPE(params, const ExtractPolyMesh_Params *); \ + { \ + const MPoly *_mpoly = mr->mpoly; \ + const int _poly_index_end = (params)->poly_range[1]; \ + for (int index_poly = (params)->poly_range[0]; index_poly < _poly_index_end; \ + index_poly += 1) { \ + const MPoly *elem_poly = &_mpoly[index_poly]; \ + (void)elem_poly; + +#define EXTRACT_POLY_FOREACH_MESH_END \ + } \ + } + +/* Iterate over polygon and loop. */ +#define EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN( \ + elem_poly, index_poly, elem_loop, index_loop, params, mr) \ + CHECK_TYPE(params, const ExtractPolyMesh_Params *); \ + { \ + const MPoly *_mpoly = mr->mpoly; \ + const MLoop *_mloop = mr->mloop; \ + const int _poly_index_end = (params)->poly_range[1]; \ + for (int index_poly = (params)->poly_range[0]; index_poly < _poly_index_end; \ + index_poly += 1) { \ + const MPoly *elem_poly = &_mpoly[index_poly]; \ + const int _index_end = elem_poly->loopstart + elem_poly->totloop; \ + for (int index_loop = elem_poly->loopstart; index_loop < _index_end; index_loop += 1) { \ + const MLoop *elem_loop = &_mloop[index_loop]; \ + (void)elem_loop; + +#define EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END \ + } \ + } \ + } + +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Mesh Elements Extract: Loose Edges + * \{ */ + +typedef struct ExtractLEdgeBMesh_Params { + const int *ledge; + int ledge_range[2]; +} ExtractLEdgeBMesh_Params; typedef void(ExtractLEdgeBMeshFn)(const MeshRenderData *mr, - int ledge_index, - BMEdge *eed, + const ExtractLEdgeBMesh_Params *params, void *data); + +#define EXTRACT_LEDGE_FOREACH_BM_BEGIN(elem_edge, index_ledge, params) \ + CHECK_TYPE(params, const ExtractLEdgeBMesh_Params *); \ + { \ + BLI_assert((mr->bm->elem_table_dirty & BM_EDGE) == 0); \ + BMEdge **_etable = mr->bm->etable; \ + const int *_ledge = (params)->ledge; \ + const int _ledge_index_end = (params)->ledge_range[1]; \ + for (int index_ledge = (params)->ledge_range[0]; index_ledge < _ledge_index_end; \ + index_ledge += 1) { \ + BMEdge *elem_edge = _etable[_ledge[index_ledge]]; \ + (void)elem_edge; /* Quiet warning when unused. */ \ + { +#define EXTRACT_LEDGE_FOREACH_BM_END \ + } \ + } \ + } + +typedef struct ExtractLEdgeMesh_Params { + const int *ledge; + int ledge_range[2]; +} ExtractLEdgeMesh_Params; typedef void(ExtractLEdgeMeshFn)(const MeshRenderData *mr, - int ledge_index, - const MEdge *medge, + const ExtractLEdgeMesh_Params *params, void *data); +#define EXTRACT_LEDGE_FOREACH_MESH_BEGIN(elem_edge, index_ledge, params, mr) \ + CHECK_TYPE(params, const ExtractLEdgeMesh_Params *); \ + { \ + const MEdge *_medge = mr->medge; \ + const int *_ledge = (params)->ledge; \ + const int _ledge_index_end = (params)->ledge_range[1]; \ + for (int index_ledge = (params)->ledge_range[0]; index_ledge < _ledge_index_end; \ + index_ledge += 1) { \ + const MEdge *elem_edge = &_medge[_ledge[index_ledge]]; \ + (void)elem_edge; /* Quiet warning when unused. */ \ + { +#define EXTRACT_LEDGE_FOREACH_MESH_END \ + } \ + } \ + } + +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Mesh Elements Extract: Loose Vertices + * \{ */ + +typedef struct ExtractLVertBMesh_Params { + const int *lvert; + int lvert_range[2]; +} ExtractLVertBMesh_Params; typedef void(ExtractLVertBMeshFn)(const MeshRenderData *mr, - int lvert_index, - BMVert *eve, + const ExtractLVertBMesh_Params *params, void *data); + +#define EXTRACT_LVERT_FOREACH_BM_BEGIN(elem_vert, index_lvert, params) \ + CHECK_TYPE(params, const ExtractLVertBMesh_Params *); \ + { \ + BLI_assert((mr->bm->elem_table_dirty & BM_FACE) == 0); \ + BMVert **vtable = mr->bm->vtable; \ + const int *lverts = (params)->lvert; \ + const int _lvert_index_end = (params)->lvert_range[1]; \ + for (int index_lvert = (params)->lvert_range[0]; index_lvert < _lvert_index_end; \ + index_lvert += 1) { \ + BMVert *elem_vert = vtable[lverts[index_lvert]]; \ + (void)elem_vert; /* Quiet warning when unused. */ \ + { +#define EXTRACT_LVERT_FOREACH_BM_END \ + } \ + } \ + } + +typedef struct ExtractLVertMesh_Params { + const int *lvert; + int lvert_range[2]; +} ExtractLVertMesh_Params; typedef void(ExtractLVertMeshFn)(const MeshRenderData *mr, - int lvert_index, - const MVert *mvert, + const ExtractLVertMesh_Params *params, void *data); + +#define EXTRACT_LVERT_FOREACH_MESH_BEGIN(elem, index_lvert, params, mr) \ + CHECK_TYPE(params, const ExtractLVertMesh_Params *); \ + { \ + const MVert *mvert = mr->mvert; \ + const int *lverts = (params)->lvert; \ + const int _lvert_index_end = (params)->lvert_range[1]; \ + for (int index_lvert = (params)->lvert_range[0]; index_lvert < _lvert_index_end; \ + index_lvert += 1) { \ + const MVert *elem = &mvert[lverts[index_lvert]]; \ + (void)elem; /* Quiet warning when unused. */ \ + { +#define EXTRACT_LVERT_FOREACH_MESH_END \ + } \ + } \ + } + +/** \} */ + +/* ---------------------------------------------------------------------- */ +/** \name Mesh Elements Extract Struct + * \{ */ + +typedef void *(ExtractInitFn)(const MeshRenderData *mr, void *buffer); typedef void(ExtractFinishFn)(const MeshRenderData *mr, void *buffer, void *data); typedef struct MeshExtract { @@ -554,8 +763,8 @@ typedef struct MeshExtract { /** Executed on one (or more if use_threading) worker thread(s). */ ExtractTriBMeshFn *iter_looptri_bm; ExtractTriMeshFn *iter_looptri_mesh; - ExtractLoopBMeshFn *iter_loop_bm; - ExtractLoopMeshFn *iter_loop_mesh; + ExtractPolyBMeshFn *iter_poly_bm; + ExtractPolyMeshFn *iter_poly_mesh; ExtractLEdgeBMeshFn *iter_ledge_bm; ExtractLEdgeMeshFn *iter_ledge_mesh; ExtractLVertBMeshFn *iter_lvert_bm; @@ -572,7 +781,7 @@ BLI_INLINE eMRIterType mesh_extract_iter_type(const MeshExtract *ext) { eMRIterType type = 0; SET_FLAG_FROM_TEST(type, (ext->iter_looptri_bm || ext->iter_looptri_mesh), MR_ITER_LOOPTRI); - SET_FLAG_FROM_TEST(type, (ext->iter_loop_bm || ext->iter_loop_mesh), MR_ITER_LOOP); + SET_FLAG_FROM_TEST(type, (ext->iter_poly_bm || ext->iter_poly_mesh), MR_ITER_POLY); SET_FLAG_FROM_TEST(type, (ext->iter_ledge_bm || ext->iter_ledge_mesh), MR_ITER_LEDGE); SET_FLAG_FROM_TEST(type, (ext->iter_lvert_bm || ext->iter_lvert_mesh), MR_ITER_LVERT); return type; @@ -611,11 +820,11 @@ static void *extract_tris_init(const MeshRenderData *mr, void *UNUSED(ibo)) } } else { - const MPoly *mpoly = mr->mpoly; - for (int p = 0; p < mr->poly_len; p++, mpoly++) { - if (!(mr->use_hide && (mpoly->flag & ME_HIDE))) { - int mat = min_ii(mpoly->mat_nr, mr->mat_len - 1); - mat_tri_len[mat] += mpoly->totloop - 2; + const MPoly *mp = mr->mpoly; + for (int mp_index = 0; mp_index < mr->poly_len; mp_index++, mp++) { + if (!(mr->use_hide && (mp->flag & ME_HIDE))) { + int mat = min_ii(mp->mat_nr, mr->mat_len - 1); + mat_tri_len[mat] += mp->totloop - 2; } } } @@ -636,36 +845,44 @@ static void *extract_tris_init(const MeshRenderData *mr, void *UNUSED(ibo)) return data; } -static void extract_tris_looptri_bmesh(const MeshRenderData *mr, - int UNUSED(t), - BMLoop **elt, - void *_data) +static void extract_tris_iter_looptri_bm(const MeshRenderData *mr, + const struct ExtractTriBMesh_Params *params, + void *_data) { - if (!BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN)) { - MeshExtract_Tri_Data *data = _data; - int *mat_tri_ofs = data->tri_mat_end; - int mat = min_ii(elt[0]->f->mat_nr, mr->mat_len - 1); - GPU_indexbuf_set_tri_verts(&data->elb, - mat_tri_ofs[mat]++, - BM_elem_index_get(elt[0]), - BM_elem_index_get(elt[1]), - BM_elem_index_get(elt[2])); + MeshExtract_Tri_Data *data = _data; + const int mat_last = mr->mat_len - 1; + EXTRACT_TRIS_LOOPTRI_FOREACH_BM_BEGIN(elt, _elt_index, params) + { + if (!BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN)) { + int *mat_tri_ofs = data->tri_mat_end; + const int mat = min_ii(elt[0]->f->mat_nr, mat_last); + GPU_indexbuf_set_tri_verts(&data->elb, + mat_tri_ofs[mat]++, + BM_elem_index_get(elt[0]), + BM_elem_index_get(elt[1]), + BM_elem_index_get(elt[2])); + } } + EXTRACT_TRIS_LOOPTRI_FOREACH_BM_END; } -static void extract_tris_looptri_mesh(const MeshRenderData *mr, - int UNUSED(t), - const MLoopTri *mlt, - void *_data) +static void extract_tris_iter_looptri_mesh(const MeshRenderData *mr, + const struct ExtractTriMesh_Params *params, + void *_data) { - const MPoly *mpoly = &mr->mpoly[mlt->poly]; - if (!(mr->use_hide && (mpoly->flag & ME_HIDE))) { - MeshExtract_Tri_Data *data = _data; - int *mat_tri_ofs = data->tri_mat_end; - int mat = min_ii(mpoly->mat_nr, mr->mat_len - 1); - GPU_indexbuf_set_tri_verts( - &data->elb, mat_tri_ofs[mat]++, mlt->tri[0], mlt->tri[1], mlt->tri[2]); + MeshExtract_Tri_Data *data = _data; + const int mat_last = mr->mat_len - 1; + EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_BEGIN(mlt, _mlt_index, params) + { + const MPoly *mp = &mr->mpoly[mlt->poly]; + if (!(mr->use_hide && (mp->flag & ME_HIDE))) { + int *mat_tri_ofs = data->tri_mat_end; + const int mat = min_ii(mp->mat_nr, mat_last); + GPU_indexbuf_set_tri_verts( + &data->elb, mat_tri_ofs[mat]++, mlt->tri[0], mlt->tri[1], mlt->tri[2]); + } } + EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_END; } static void extract_tris_finish(const MeshRenderData *mr, void *ibo, void *_data) @@ -677,8 +894,8 @@ static void extract_tris_finish(const MeshRenderData *mr, void *ibo, void *_data BLI_assert(mr->cache->surface_per_mat[0]->elem == ibo); for (int i = 0; i < mr->mat_len; i++) { /* Multiply by 3 because these are triangle indices. */ - int start = data->tri_mat_start[i] * 3; - int len = data->tri_mat_end[i] * 3 - data->tri_mat_start[i] * 3; + const int start = data->tri_mat_start[i] * 3; + const int len = data->tri_mat_end[i] * 3 - data->tri_mat_start[i] * 3; GPUIndexBuf *sub_ibo = GPU_indexbuf_create_subrange(ibo, start, len); /* WARNING: We modify the #GPUBatch here! */ GPU_batch_elembuf_set(mr->cache->surface_per_mat[i], sub_ibo, true); @@ -691,8 +908,8 @@ static void extract_tris_finish(const MeshRenderData *mr, void *ibo, void *_data static const MeshExtract extract_tris = { .init = extract_tris_init, - .iter_looptri_bm = extract_tris_looptri_bmesh, - .iter_looptri_mesh = extract_tris_looptri_mesh, + .iter_looptri_bm = extract_tris_iter_looptri_bm, + .iter_looptri_mesh = extract_tris_iter_looptri_mesh, .finish = extract_tris_finish, .data_flag = 0, .use_threading = false, @@ -713,71 +930,113 @@ static void *extract_lines_init(const MeshRenderData *mr, void *UNUSED(buf)) return elb; } -static void extract_lines_loop_bmesh(const MeshRenderData *UNUSED(mr), - int l, - BMLoop *loop, - void *elb) -{ - if (!BM_elem_flag_test(loop->e, BM_ELEM_HIDDEN)) { - GPU_indexbuf_set_line_verts(elb, BM_elem_index_get(loop->e), l, BM_elem_index_get(loop->next)); - } - else { - GPU_indexbuf_set_line_restart(elb, BM_elem_index_get(loop->e)); +static void extract_lines_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *elb) +{ + /* Using poly & loop iterator would complicate accessing the adjacent loop. */ + EXTRACT_POLY_FOREACH_BM_BEGIN(f, f_index, params, mr) + { + BMLoop *l_iter, *l_first; + /* Use #BMLoop.prev to match mesh order (to avoid minor differences in data extraction). */ + l_iter = l_first = BM_FACE_FIRST_LOOP(f)->prev; + do { + if (!BM_elem_flag_test(l_iter->e, BM_ELEM_HIDDEN)) { + GPU_indexbuf_set_line_verts(elb, + BM_elem_index_get(l_iter->e), + BM_elem_index_get(l_iter), + BM_elem_index_get(l_iter->next)); + } + else { + GPU_indexbuf_set_line_restart(elb, BM_elem_index_get(l_iter->e)); + } + } while ((l_iter = l_iter->next) != l_first); } + EXTRACT_POLY_FOREACH_BM_END; } -static void extract_lines_loop_mesh(const MeshRenderData *mr, - int l, - const MLoop *mloop, - int UNUSED(p), - const MPoly *mpoly, - void *elb) +static void extract_lines_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *elb) { - const MEdge *medge = &mr->medge[mloop->e]; - if (!((mr->use_hide && (medge->flag & ME_HIDE)) || - ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) && - (mr->e_origindex[mloop->e] == ORIGINDEX_NONE)))) { - int loopend = mpoly->totloop + mpoly->loopstart - 1; - int other_loop = (l == loopend) ? mpoly->loopstart : (l + 1); - GPU_indexbuf_set_line_verts(elb, mloop->e, l, other_loop); + /* Using poly & loop iterator would complicate accessing the adjacent loop. */ + const MLoop *mloop = mr->mloop; + const MEdge *medge = mr->medge; + if (mr->use_hide || (mr->extract_type == MR_EXTRACT_MAPPED) || (mr->e_origindex != NULL)) { + EXTRACT_POLY_FOREACH_MESH_BEGIN(mp, mp_index, params, mr) + { + const int ml_index_last = mp->loopstart + (mp->totloop - 1); + int ml_index = ml_index_last, ml_index_next = mp->loopstart; + do { + const MLoop *ml = &mloop[ml_index]; + const MEdge *med = &medge[ml->e]; + if (!((mr->use_hide && (med->flag & ME_HIDE)) || + ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) && + (mr->e_origindex[ml->e] == ORIGINDEX_NONE)))) { + GPU_indexbuf_set_line_verts(elb, ml->e, ml_index, ml_index_next); + } + else { + GPU_indexbuf_set_line_restart(elb, ml->e); + } + } while ((ml_index = ml_index_next++) != ml_index_last); + } + EXTRACT_POLY_FOREACH_MESH_END; } else { - GPU_indexbuf_set_line_restart(elb, mloop->e); + EXTRACT_POLY_FOREACH_MESH_BEGIN(mp, mp_index, params, mr) + { + const int ml_index_last = mp->loopstart + (mp->totloop - 1); + int ml_index = ml_index_last, ml_index_next = mp->loopstart; + do { + const MLoop *ml = &mloop[ml_index]; + GPU_indexbuf_set_line_verts(elb, ml->e, ml_index, ml_index_next); + } while ((ml_index = ml_index_next++) != ml_index_last); + } + EXTRACT_POLY_FOREACH_MESH_END; } } -static void extract_lines_ledge_bmesh(const MeshRenderData *mr, int e, BMEdge *eed, void *elb) +static void extract_lines_iter_ledge_bm(const MeshRenderData *mr, + const ExtractLEdgeBMesh_Params *params, + void *elb) { - int ledge_idx = mr->edge_len + e; - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - int l = mr->loop_len + e * 2; - GPU_indexbuf_set_line_verts(elb, ledge_idx, l, l + 1); - } - else { - GPU_indexbuf_set_line_restart(elb, ledge_idx); + EXTRACT_LEDGE_FOREACH_BM_BEGIN(eed, ledge_index, params) + { + const int l_index_offset = mr->edge_len + ledge_index; + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + const int l_index = mr->loop_len + ledge_index * 2; + GPU_indexbuf_set_line_verts(elb, l_index_offset, l_index, l_index + 1); + } + else { + GPU_indexbuf_set_line_restart(elb, l_index_offset); + } + /* Don't render the edge twice. */ + GPU_indexbuf_set_line_restart(elb, BM_elem_index_get(eed)); } - /* Don't render the edge twice. */ - GPU_indexbuf_set_line_restart(elb, BM_elem_index_get(eed)); + EXTRACT_LEDGE_FOREACH_BM_END; } -static void extract_lines_ledge_mesh(const MeshRenderData *mr, - int e, - const MEdge *medge, - void *elb) +static void extract_lines_iter_ledge_mesh(const MeshRenderData *mr, + const ExtractLEdgeMesh_Params *params, + void *elb) { - int ledge_idx = mr->edge_len + e; - int edge_idx = mr->ledges[e]; - if (!((mr->use_hide && (medge->flag & ME_HIDE)) || - ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) && - (mr->e_origindex[edge_idx] == ORIGINDEX_NONE)))) { - int l = mr->loop_len + e * 2; - GPU_indexbuf_set_line_verts(elb, ledge_idx, l, l + 1); - } - else { - GPU_indexbuf_set_line_restart(elb, ledge_idx); + EXTRACT_LEDGE_FOREACH_MESH_BEGIN(med, ledge_index, params, mr) + { + const int l_index_offset = mr->edge_len + ledge_index; + const int e_index = mr->ledges[ledge_index]; + if (!((mr->use_hide && (med->flag & ME_HIDE)) || + ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) && + (mr->e_origindex[e_index] == ORIGINDEX_NONE)))) { + const int l_index = mr->loop_len + ledge_index * 2; + GPU_indexbuf_set_line_verts(elb, l_index_offset, l_index, l_index + 1); + } + else { + GPU_indexbuf_set_line_restart(elb, l_index_offset); + } + /* Don't render the edge twice. */ + GPU_indexbuf_set_line_restart(elb, e_index); } - /* Don't render the edge twice. */ - GPU_indexbuf_set_line_restart(elb, edge_idx); + EXTRACT_LEDGE_FOREACH_MESH_END; } static void extract_lines_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *elb) @@ -788,10 +1047,10 @@ static void extract_lines_finish(const MeshRenderData *UNUSED(mr), void *ibo, vo static const MeshExtract extract_lines = { .init = extract_lines_init, - .iter_loop_bm = extract_lines_loop_bmesh, - .iter_loop_mesh = extract_lines_loop_mesh, - .iter_ledge_bm = extract_lines_ledge_bmesh, - .iter_ledge_mesh = extract_lines_ledge_mesh, + .iter_poly_bm = extract_lines_iter_poly_bm, + .iter_poly_mesh = extract_lines_iter_poly_mesh, + .iter_ledge_bm = extract_lines_iter_ledge_bm, + .iter_ledge_mesh = extract_lines_iter_ledge_mesh, .finish = extract_lines_finish, .data_flag = 0, .use_threading = false, @@ -822,10 +1081,10 @@ static void extract_lines_with_lines_loose_finish(const MeshRenderData *mr, void static const MeshExtract extract_lines_with_lines_loose = { .init = extract_lines_init, - .iter_loop_bm = extract_lines_loop_bmesh, - .iter_loop_mesh = extract_lines_loop_mesh, - .iter_ledge_bm = extract_lines_ledge_bmesh, - .iter_ledge_mesh = extract_lines_ledge_mesh, + .iter_poly_bm = extract_lines_iter_poly_bm, + .iter_poly_mesh = extract_lines_iter_poly_mesh, + .iter_ledge_bm = extract_lines_iter_ledge_bm, + .iter_ledge_mesh = extract_lines_iter_ledge_mesh, .finish = extract_lines_with_lines_loose_finish, .data_flag = 0, .use_threading = false, @@ -844,77 +1103,101 @@ static void *extract_points_init(const MeshRenderData *mr, void *UNUSED(buf)) return elb; } -BLI_INLINE void vert_set_bmesh(GPUIndexBufBuilder *elb, BMVert *eve, int loop) +BLI_INLINE void vert_set_bm(GPUIndexBufBuilder *elb, BMVert *eve, int l_index) { - int vert_idx = BM_elem_index_get(eve); + const int v_index = BM_elem_index_get(eve); if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - GPU_indexbuf_set_point_vert(elb, vert_idx, loop); + GPU_indexbuf_set_point_vert(elb, v_index, l_index); } else { - GPU_indexbuf_set_point_restart(elb, vert_idx); + GPU_indexbuf_set_point_restart(elb, v_index); } } BLI_INLINE void vert_set_mesh(GPUIndexBufBuilder *elb, const MeshRenderData *mr, - int vert_idx, - int loop) + const int v_index, + const int l_index) { - const MVert *mvert = &mr->mvert[vert_idx]; - if (!((mr->use_hide && (mvert->flag & ME_HIDE)) || + const MVert *mv = &mr->mvert[v_index]; + if (!((mr->use_hide && (mv->flag & ME_HIDE)) || ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->v_origindex) && - (mr->v_origindex[vert_idx] == ORIGINDEX_NONE)))) { - GPU_indexbuf_set_point_vert(elb, vert_idx, loop); + (mr->v_origindex[v_index] == ORIGINDEX_NONE)))) { + GPU_indexbuf_set_point_vert(elb, v_index, l_index); } else { - GPU_indexbuf_set_point_restart(elb, vert_idx); + GPU_indexbuf_set_point_restart(elb, v_index); } } -static void extract_points_loop_bmesh(const MeshRenderData *UNUSED(mr), - int l, - BMLoop *loop, - void *elb) +static void extract_points_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *elb) { - vert_set_bmesh(elb, loop->v, l); + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + vert_set_bm(elb, l->v, l_index); + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); } -static void extract_points_loop_mesh(const MeshRenderData *mr, - int l, - const MLoop *mloop, - int UNUSED(p), - const MPoly *UNUSED(mpoly), - void *elb) +static void extract_points_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *elb) { - vert_set_mesh(elb, mr, mloop->v, l); + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + vert_set_mesh(elb, mr, ml->v, ml_index); + } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } -static void extract_points_ledge_bmesh(const MeshRenderData *mr, int e, BMEdge *eed, void *elb) +static void extract_points_iter_ledge_bm(const MeshRenderData *mr, + const ExtractLEdgeBMesh_Params *params, + void *elb) { - vert_set_bmesh(elb, eed->v1, mr->loop_len + e * 2); - vert_set_bmesh(elb, eed->v2, mr->loop_len + e * 2 + 1); + EXTRACT_LEDGE_FOREACH_BM_BEGIN(eed, ledge_index, params) + { + vert_set_bm(elb, eed->v1, mr->loop_len + (ledge_index * 2)); + vert_set_bm(elb, eed->v2, mr->loop_len + (ledge_index * 2) + 1); + } + EXTRACT_LEDGE_FOREACH_BM_END; } -static void extract_points_ledge_mesh(const MeshRenderData *mr, - int e, - const MEdge *medge, - void *elb) +static void extract_points_iter_ledge_mesh(const MeshRenderData *mr, + const ExtractLEdgeMesh_Params *params, + void *elb) { - vert_set_mesh(elb, mr, medge->v1, mr->loop_len + e * 2); - vert_set_mesh(elb, mr, medge->v2, mr->loop_len + e * 2 + 1); + EXTRACT_LEDGE_FOREACH_MESH_BEGIN(med, ledge_index, params, mr) + { + vert_set_mesh(elb, mr, med->v1, mr->loop_len + (ledge_index * 2)); + vert_set_mesh(elb, mr, med->v2, mr->loop_len + (ledge_index * 2) + 1); + } + EXTRACT_LEDGE_FOREACH_MESH_END; } -static void extract_points_lvert_bmesh(const MeshRenderData *mr, int v, BMVert *eve, void *elb) +static void extract_points_iter_lvert_bm(const MeshRenderData *mr, + const ExtractLVertBMesh_Params *params, + void *elb) { - vert_set_bmesh(elb, eve, mr->loop_len + mr->edge_loose_len * 2 + v); + const int offset = mr->loop_len + (mr->edge_loose_len * 2); + EXTRACT_LVERT_FOREACH_BM_BEGIN(eve, lvert_index, params) + { + vert_set_bm(elb, eve, offset + lvert_index); + } + EXTRACT_LVERT_FOREACH_BM_END; } -static void extract_points_lvert_mesh(const MeshRenderData *mr, - int v, - const MVert *UNUSED(mvert), - void *elb) +static void extract_points_iter_lvert_mesh(const MeshRenderData *mr, + const ExtractLVertMesh_Params *params, + void *elb) { - vert_set_mesh(elb, mr, mr->lverts[v], mr->loop_len + mr->edge_loose_len * 2 + v); + const int offset = mr->loop_len + (mr->edge_loose_len * 2); + EXTRACT_LVERT_FOREACH_MESH_BEGIN(mv, lvert_index, params, mr) + { + vert_set_mesh(elb, mr, mr->lverts[lvert_index], offset + lvert_index); + } + EXTRACT_LVERT_FOREACH_MESH_END; } static void extract_points_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *elb) @@ -925,12 +1208,12 @@ static void extract_points_finish(const MeshRenderData *UNUSED(mr), void *ibo, v static const MeshExtract extract_points = { .init = extract_points_init, - .iter_loop_bm = extract_points_loop_bmesh, - .iter_loop_mesh = extract_points_loop_mesh, - .iter_ledge_bm = extract_points_ledge_bmesh, - .iter_ledge_mesh = extract_points_ledge_mesh, - .iter_lvert_bm = extract_points_lvert_bmesh, - .iter_lvert_mesh = extract_points_lvert_mesh, + .iter_poly_bm = extract_points_iter_poly_bm, + .iter_poly_mesh = extract_points_iter_poly_mesh, + .iter_ledge_bm = extract_points_iter_ledge_bm, + .iter_ledge_mesh = extract_points_iter_ledge_mesh, + .iter_lvert_bm = extract_points_iter_lvert_bm, + .iter_lvert_mesh = extract_points_iter_lvert_mesh, .finish = extract_points_finish, .data_flag = 0, .use_threading = false, @@ -949,34 +1232,51 @@ static void *extract_fdots_init(const MeshRenderData *mr, void *UNUSED(buf)) return elb; } -static void extract_fdots_loop_bmesh(const MeshRenderData *UNUSED(mr), - int UNUSED(l), - BMLoop *loop, - void *elb) +static void extract_fdots_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *elb) { - int face_idx = BM_elem_index_get(loop->f); - if (!BM_elem_flag_test(loop->f, BM_ELEM_HIDDEN)) { - GPU_indexbuf_set_point_vert(elb, face_idx, face_idx); - } - else { - GPU_indexbuf_set_point_restart(elb, face_idx); + EXTRACT_POLY_FOREACH_BM_BEGIN(f, f_index, params, mr) + { + if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { + GPU_indexbuf_set_point_vert(elb, f_index, f_index); + } + else { + GPU_indexbuf_set_point_restart(elb, f_index); + } } + EXTRACT_POLY_FOREACH_BM_END; } -static void extract_fdots_loop_mesh(const MeshRenderData *mr, - int UNUSED(l), - const MLoop *mloop, - int p, - const MPoly *mpoly, - void *elb) +static void extract_fdots_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *elb) { - const MVert *mvert = &mr->mvert[mloop->v]; - if ((!mr->use_subsurf_fdots || (mvert->flag & ME_VERT_FACEDOT)) && - !(mr->use_hide && (mpoly->flag & ME_HIDE))) { - GPU_indexbuf_set_point_vert(elb, p, p); + if (mr->use_subsurf_fdots) { + /* Check #ME_VERT_FACEDOT. */ + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + const MVert *mv = &mr->mvert[ml->v]; + if ((mv->flag & ME_VERT_FACEDOT) && !(mr->use_hide && (mp->flag & ME_HIDE))) { + GPU_indexbuf_set_point_vert(elb, mp_index, mp_index); + } + else { + GPU_indexbuf_set_point_restart(elb, mp_index); + } + } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } else { - GPU_indexbuf_set_point_restart(elb, p); + EXTRACT_POLY_FOREACH_MESH_BEGIN(mp, mp_index, params, mr) + { + if (!(mr->use_hide && (mp->flag & ME_HIDE))) { + GPU_indexbuf_set_point_vert(elb, mp_index, mp_index); + } + else { + GPU_indexbuf_set_point_restart(elb, mp_index); + } + } + EXTRACT_POLY_FOREACH_MESH_END; } } @@ -988,8 +1288,8 @@ static void extract_fdots_finish(const MeshRenderData *UNUSED(mr), void *ibo, vo static const MeshExtract extract_fdots = { .init = extract_fdots_init, - .iter_loop_bm = extract_fdots_loop_bmesh, - .iter_loop_mesh = extract_fdots_loop_mesh, + .iter_poly_bm = extract_fdots_iter_poly_bm, + .iter_poly_mesh = extract_fdots_iter_poly_mesh, .finish = extract_fdots_finish, .data_flag = 0, .use_threading = false, @@ -1015,48 +1315,49 @@ static void *extract_lines_paint_mask_init(const MeshRenderData *mr, void *UNUSE return data; } -static void extract_lines_paint_mask_loop_mesh(const MeshRenderData *mr, - int l, - const MLoop *mloop, - int UNUSED(p), - const MPoly *mpoly, - void *_data) -{ - MeshExtract_LinePaintMask_Data *data = (MeshExtract_LinePaintMask_Data *)_data; - const int edge_idx = mloop->e; - const MEdge *medge = &mr->medge[edge_idx]; - if (!((mr->use_hide && (medge->flag & ME_HIDE)) || - ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) && - (mr->e_origindex[edge_idx] == ORIGINDEX_NONE)))) { - - int loopend = mpoly->totloop + mpoly->loopstart - 1; - int other_loop = (l == loopend) ? mpoly->loopstart : (l + 1); - if (mpoly->flag & ME_FACE_SEL) { - if (BLI_BITMAP_TEST_AND_SET_ATOMIC(data->select_map, edge_idx)) { - /* Hide edge as it has more than 2 selected loop. */ - GPU_indexbuf_set_line_restart(&data->elb, edge_idx); +static void extract_lines_paint_mask_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *_data) +{ + MeshExtract_LinePaintMask_Data *data = _data; + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + const int e_index = ml->e; + const MEdge *me = &mr->medge[e_index]; + if (!((mr->use_hide && (me->flag & ME_HIDE)) || + ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->e_origindex) && + (mr->e_origindex[e_index] == ORIGINDEX_NONE)))) { + + const int ml_index_last = mp->totloop + mp->loopstart - 1; + const int ml_index_other = (ml_index == ml_index_last) ? mp->loopstart : (ml_index + 1); + if (mp->flag & ME_FACE_SEL) { + if (BLI_BITMAP_TEST_AND_SET_ATOMIC(data->select_map, e_index)) { + /* Hide edge as it has more than 2 selected loop. */ + GPU_indexbuf_set_line_restart(&data->elb, e_index); + } + else { + /* First selected loop. Set edge visible, overwriting any unselected loop. */ + GPU_indexbuf_set_line_verts(&data->elb, e_index, ml_index, ml_index_other); + } } else { - /* First selected loop. Set edge visible, overwriting any unselected loop. */ - GPU_indexbuf_set_line_verts(&data->elb, edge_idx, l, other_loop); + /* Set theses unselected loop only if this edge has no other selected loop. */ + if (!BLI_BITMAP_TEST(data->select_map, e_index)) { + GPU_indexbuf_set_line_verts(&data->elb, e_index, ml_index, ml_index_other); + } } } else { - /* Set theses unselected loop only if this edge has no other selected loop. */ - if (!BLI_BITMAP_TEST(data->select_map, edge_idx)) { - GPU_indexbuf_set_line_verts(&data->elb, edge_idx, l, other_loop); - } + GPU_indexbuf_set_line_restart(&data->elb, e_index); } } - else { - GPU_indexbuf_set_line_restart(&data->elb, edge_idx); - } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } static void extract_lines_paint_mask_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *_data) { - MeshExtract_LinePaintMask_Data *data = (MeshExtract_LinePaintMask_Data *)_data; + MeshExtract_LinePaintMask_Data *data = _data; GPU_indexbuf_build_in_place(&data->elb, ibo); MEM_freeN(data); @@ -1064,7 +1365,7 @@ static void extract_lines_paint_mask_finish(const MeshRenderData *UNUSED(mr), static const MeshExtract extract_lines_paint_mask = { .init = extract_lines_paint_mask_init, - .iter_loop_mesh = extract_lines_paint_mask_loop_mesh, + .iter_poly_mesh = extract_lines_paint_mask_iter_poly_mesh, .finish = extract_lines_paint_mask_finish, .data_flag = 0, .use_threading = false, @@ -1143,42 +1444,48 @@ BLI_INLINE void lines_adjacency_triangle( } } -static void extract_lines_adjacency_looptri_bmesh(const MeshRenderData *UNUSED(mr), - int UNUSED(t), - BMLoop **elt, - void *data) +static void extract_lines_adjacency_iter_looptri_bm(const MeshRenderData *UNUSED(mr), + const struct ExtractTriBMesh_Params *params, + void *data) { - if (!BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN)) { - lines_adjacency_triangle(BM_elem_index_get(elt[0]->v), - BM_elem_index_get(elt[1]->v), - BM_elem_index_get(elt[2]->v), - BM_elem_index_get(elt[0]), - BM_elem_index_get(elt[1]), - BM_elem_index_get(elt[2]), - data); + EXTRACT_TRIS_LOOPTRI_FOREACH_BM_BEGIN(elt, _elt_index, params) + { + if (!BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN)) { + lines_adjacency_triangle(BM_elem_index_get(elt[0]->v), + BM_elem_index_get(elt[1]->v), + BM_elem_index_get(elt[2]->v), + BM_elem_index_get(elt[0]), + BM_elem_index_get(elt[1]), + BM_elem_index_get(elt[2]), + data); + } } + EXTRACT_TRIS_LOOPTRI_FOREACH_BM_END; } -static void extract_lines_adjacency_looptri_mesh(const MeshRenderData *mr, - int UNUSED(t), - const MLoopTri *mlt, - void *data) +static void extract_lines_adjacency_iter_looptri_mesh(const MeshRenderData *mr, + const struct ExtractTriMesh_Params *params, + void *data) { - const MPoly *mpoly = &mr->mpoly[mlt->poly]; - if (!(mr->use_hide && (mpoly->flag & ME_HIDE))) { - lines_adjacency_triangle(mr->mloop[mlt->tri[0]].v, - mr->mloop[mlt->tri[1]].v, - mr->mloop[mlt->tri[2]].v, - mlt->tri[0], - mlt->tri[1], - mlt->tri[2], - data); + EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_BEGIN(mlt, _mlt_index, params) + { + const MPoly *mp = &mr->mpoly[mlt->poly]; + if (!(mr->use_hide && (mp->flag & ME_HIDE))) { + lines_adjacency_triangle(mr->mloop[mlt->tri[0]].v, + mr->mloop[mlt->tri[1]].v, + mr->mloop[mlt->tri[2]].v, + mlt->tri[0], + mlt->tri[1], + mlt->tri[2], + data); + } } + EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_END; } static void extract_lines_adjacency_finish(const MeshRenderData *mr, void *ibo, void *_data) { - MeshExtract_LineAdjacency_Data *data = (MeshExtract_LineAdjacency_Data *)_data; + MeshExtract_LineAdjacency_Data *data = _data; /* Create edges for remaining non manifold edges. */ EdgeHashIterator *ehi = BLI_edgehashIterator_new(data->eh); for (; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { @@ -1209,8 +1516,8 @@ static void extract_lines_adjacency_finish(const MeshRenderData *mr, void *ibo, static const MeshExtract extract_lines_adjacency = { .init = extract_lines_adjacency_init, - .iter_looptri_bm = extract_lines_adjacency_looptri_bmesh, - .iter_looptri_mesh = extract_lines_adjacency_looptri_mesh, + .iter_looptri_bm = extract_lines_adjacency_iter_looptri_bm, + .iter_looptri_mesh = extract_lines_adjacency_iter_looptri_mesh, .finish = extract_lines_adjacency_finish, .data_flag = 0, .use_threading = false, @@ -1243,44 +1550,50 @@ BLI_INLINE void edituv_tri_add( } } -static void extract_edituv_tris_looptri_bmesh(const MeshRenderData *UNUSED(mr), - int UNUSED(t), - BMLoop **elt, - void *data) +static void extract_edituv_tris_iter_looptri_bm(const MeshRenderData *UNUSED(mr), + const struct ExtractTriBMesh_Params *params, + void *data) { - edituv_tri_add(data, - BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN), - BM_elem_flag_test(elt[0]->f, BM_ELEM_SELECT), - BM_elem_index_get(elt[0]), - BM_elem_index_get(elt[1]), - BM_elem_index_get(elt[2])); + EXTRACT_TRIS_LOOPTRI_FOREACH_BM_BEGIN(elt, _elt_index, params) + { + edituv_tri_add(data, + BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN), + BM_elem_flag_test(elt[0]->f, BM_ELEM_SELECT), + BM_elem_index_get(elt[0]), + BM_elem_index_get(elt[1]), + BM_elem_index_get(elt[2])); + } + EXTRACT_TRIS_LOOPTRI_FOREACH_BM_END; } -static void extract_edituv_tris_looptri_mesh(const MeshRenderData *mr, - int UNUSED(t), - const MLoopTri *mlt, - void *data) +static void extract_edituv_tris_iter_looptri_mesh(const MeshRenderData *mr, + const struct ExtractTriMesh_Params *params, + void *data) { - const MPoly *mpoly = &mr->mpoly[mlt->poly]; - edituv_tri_add(data, - (mpoly->flag & ME_HIDE) != 0, - (mpoly->flag & ME_FACE_SEL) != 0, - mlt->tri[0], - mlt->tri[1], - mlt->tri[2]); + EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_BEGIN(mlt, _mlt_index, params) + { + 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]); + } + EXTRACT_TRIS_LOOPTRI_FOREACH_MESH_END; } static void extract_edituv_tris_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *data) { - MeshExtract_EditUvElem_Data *extract_data = (MeshExtract_EditUvElem_Data *)data; + MeshExtract_EditUvElem_Data *extract_data = data; GPU_indexbuf_build_in_place(&extract_data->elb, ibo); MEM_freeN(extract_data); } static const MeshExtract extract_edituv_tris = { .init = extract_edituv_tris_init, - .iter_looptri_bm = extract_edituv_tris_looptri_bmesh, - .iter_looptri_mesh = extract_edituv_tris_looptri_mesh, + .iter_looptri_bm = extract_edituv_tris_iter_looptri_bm, + .iter_looptri_mesh = extract_edituv_tris_iter_looptri_mesh, .finish = extract_edituv_tris_finish, .data_flag = 0, .use_threading = false, @@ -1309,46 +1622,50 @@ BLI_INLINE void edituv_edge_add( } } -static void extract_edituv_lines_loop_bmesh(const MeshRenderData *UNUSED(mr), - int l, - BMLoop *loop, - void *data) +static void extract_edituv_lines_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *data) { - edituv_edge_add(data, - BM_elem_flag_test(loop->f, BM_ELEM_HIDDEN), - BM_elem_flag_test(loop->f, BM_ELEM_SELECT), - l, - BM_elem_index_get(loop->next)); + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(loop, l_index, params, mr) + { + edituv_edge_add(data, + BM_elem_flag_test(loop->f, BM_ELEM_HIDDEN), + BM_elem_flag_test(loop->f, BM_ELEM_SELECT), + l_index, + BM_elem_index_get(loop->next)); + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(loop); } -static void extract_edituv_lines_loop_mesh(const MeshRenderData *mr, - int loop_idx, - const MLoop *mloop, - int UNUSED(p), - const MPoly *mpoly, - void *data) +static void extract_edituv_lines_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *data) { - int loopend = mpoly->totloop + mpoly->loopstart - 1; - int loop_next_idx = (loop_idx == loopend) ? mpoly->loopstart : (loop_idx + 1); - const bool real_edge = (mr->e_origindex == NULL || mr->e_origindex[mloop->e] != ORIGINDEX_NONE); - edituv_edge_add(data, - (mpoly->flag & ME_HIDE) != 0 || !real_edge, - (mpoly->flag & ME_FACE_SEL) != 0, - loop_idx, - loop_next_idx); + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + const int ml_index_last = mp->totloop + mp->loopstart - 1; + const int ml_index_next = (ml_index == ml_index_last) ? mp->loopstart : (ml_index + 1); + const bool real_edge = (mr->e_origindex == NULL || 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); + } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } static void extract_edituv_lines_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *data) { - MeshExtract_EditUvElem_Data *extract_data = (MeshExtract_EditUvElem_Data *)data; + MeshExtract_EditUvElem_Data *extract_data = data; GPU_indexbuf_build_in_place(&extract_data->elb, ibo); MEM_freeN(extract_data); } static const MeshExtract extract_edituv_lines = { .init = extract_edituv_lines_init, - .iter_loop_bm = extract_edituv_lines_loop_bmesh, - .iter_loop_mesh = extract_edituv_lines_loop_mesh, + .iter_poly_bm = extract_edituv_lines_iter_poly_bm, + .iter_poly_mesh = extract_edituv_lines_iter_poly_mesh, .finish = extract_edituv_lines_finish, .data_flag = 0, .use_threading = false, @@ -1379,41 +1696,45 @@ BLI_INLINE void edituv_point_add(MeshExtract_EditUvElem_Data *data, } } -static void extract_edituv_points_loop_bmesh(const MeshRenderData *UNUSED(mr), - int l, - BMLoop *loop, - void *data) +static void extract_edituv_points_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *data) { - edituv_point_add(data, - BM_elem_flag_test(loop->f, BM_ELEM_HIDDEN), - BM_elem_flag_test(loop->f, BM_ELEM_SELECT), - l); + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + edituv_point_add(data, + BM_elem_flag_test(l->f, BM_ELEM_HIDDEN), + BM_elem_flag_test(l->f, BM_ELEM_SELECT), + l_index); + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); } -static void extract_edituv_points_loop_mesh(const MeshRenderData *mr, - int l, - const MLoop *mloop, - int UNUSED(p), - const MPoly *mpoly, - void *data) +static void extract_edituv_points_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *data) { - const bool real_vert = (mr->extract_type == MR_EXTRACT_MAPPED && (mr->v_origindex) && - mr->v_origindex[mloop->v] != ORIGINDEX_NONE); - edituv_point_add( - data, ((mpoly->flag & ME_HIDE) != 0) || !real_vert, (mpoly->flag & ME_FACE_SEL) != 0, l); + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + const bool real_vert = (mr->extract_type == MR_EXTRACT_MAPPED && (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); + } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } static void extract_edituv_points_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *data) { - MeshExtract_EditUvElem_Data *extract_data = (MeshExtract_EditUvElem_Data *)data; + MeshExtract_EditUvElem_Data *extract_data = data; GPU_indexbuf_build_in_place(&extract_data->elb, ibo); MEM_freeN(extract_data); } static const MeshExtract extract_edituv_points = { .init = extract_edituv_points_init, - .iter_loop_bm = extract_edituv_points_loop_bmesh, - .iter_loop_mesh = extract_edituv_points_loop_mesh, + .iter_poly_bm = extract_edituv_points_iter_poly_bm, + .iter_poly_mesh = extract_edituv_points_iter_poly_mesh, .finish = extract_edituv_points_finish, .data_flag = 0, .use_threading = false, @@ -1437,55 +1758,72 @@ static void *extract_edituv_fdots_init(const MeshRenderData *mr, void *UNUSED(ib BLI_INLINE void edituv_facedot_add(MeshExtract_EditUvElem_Data *data, bool hidden, bool selected, - int face_idx) + int face_index) { if (!hidden && (data->sync_selection || selected)) { - GPU_indexbuf_set_point_vert(&data->elb, face_idx, face_idx); + GPU_indexbuf_set_point_vert(&data->elb, face_index, face_index); } else { - GPU_indexbuf_set_point_restart(&data->elb, face_idx); + GPU_indexbuf_set_point_restart(&data->elb, face_index); } } -static void extract_edituv_fdots_loop_bmesh(const MeshRenderData *UNUSED(mr), - int UNUSED(l), - BMLoop *loop, - void *data) +static void extract_edituv_fdots_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *data) { - edituv_facedot_add(data, - BM_elem_flag_test(loop->f, BM_ELEM_HIDDEN), - BM_elem_flag_test(loop->f, BM_ELEM_SELECT), - BM_elem_index_get(loop->f)); + EXTRACT_POLY_FOREACH_BM_BEGIN(f, f_index, params, mr) + { + edituv_facedot_add( + data, BM_elem_flag_test(f, BM_ELEM_HIDDEN), BM_elem_flag_test(f, BM_ELEM_SELECT), f_index); + } + EXTRACT_POLY_FOREACH_BM_END; } -static void extract_edituv_fdots_loop_mesh(const MeshRenderData *mr, - int UNUSED(l), - const MLoop *mloop, - int p, - const MPoly *mpoly, - void *data) +static void extract_edituv_fdots_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *data) { - const bool real_fdot = (mr->extract_type == MR_EXTRACT_MAPPED && mr->p_origindex && - mr->p_origindex[p] != ORIGINDEX_NONE); - const bool subd_fdot = (!mr->use_subsurf_fdots || - (mr->mvert[mloop->v].flag & ME_VERT_FACEDOT) != 0); - edituv_facedot_add(data, - ((mpoly->flag & ME_HIDE) != 0) || !real_fdot || !subd_fdot, - (mpoly->flag & ME_FACE_SEL) != 0, - p); + if (mr->use_subsurf_fdots) { + /* Check #ME_VERT_FACEDOT. */ + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + const bool real_fdot = (mr->extract_type == MR_EXTRACT_MAPPED && mr->p_origindex && + mr->p_origindex[mp_index] != ORIGINDEX_NONE); + const bool subd_fdot = (!mr->use_subsurf_fdots || + (mr->mvert[ml->v].flag & ME_VERT_FACEDOT) != 0); + edituv_facedot_add(data, + ((mp->flag & ME_HIDE) != 0) || !real_fdot || !subd_fdot, + (mp->flag & ME_FACE_SEL) != 0, + mp_index); + } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; + } + else { + EXTRACT_POLY_FOREACH_MESH_BEGIN(mp, mp_index, params, mr) + { + const bool real_fdot = (mr->extract_type == MR_EXTRACT_MAPPED && 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); + } + EXTRACT_POLY_FOREACH_MESH_END; + } } static void extract_edituv_fdots_finish(const MeshRenderData *UNUSED(mr), void *ibo, void *_data) { - MeshExtract_EditUvElem_Data *data = (MeshExtract_EditUvElem_Data *)_data; + MeshExtract_EditUvElem_Data *data = _data; GPU_indexbuf_build_in_place(&data->elb, ibo); MEM_freeN(data); } static const MeshExtract extract_edituv_fdots = { .init = extract_edituv_fdots_init, - .iter_loop_bm = extract_edituv_fdots_loop_bmesh, - .iter_loop_mesh = extract_edituv_fdots_loop_mesh, + .iter_poly_bm = extract_edituv_fdots_iter_poly_bm, + .iter_poly_mesh = extract_edituv_fdots_iter_poly_mesh, .finish = extract_edituv_fdots_finish, .data_flag = 0, .use_threading = false, @@ -1535,95 +1873,122 @@ static void *extract_pos_nor_init(const MeshRenderData *mr, void *buf) } } else { - const MVert *mvert = mr->mvert; - for (int v = 0; v < mr->vert_len; v++, mvert++) { - data->packed_nor[v] = GPU_normal_convert_i10_s3(mvert->no); + const MVert *mv = mr->mvert; + for (int v = 0; v < mr->vert_len; v++, mv++) { + data->packed_nor[v] = GPU_normal_convert_i10_s3(mv->no); } } return data; } -static void extract_pos_nor_loop_bmesh(const MeshRenderData *mr, int l, BMLoop *loop, void *_data) +static void extract_pos_nor_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *_data) { MeshExtract_PosNor_Data *data = _data; - PosNorLoop *vert = data->vbo_data + l; - copy_v3_v3(vert->pos, bm_vert_co_get(mr, loop->v)); - vert->nor = data->packed_nor[BM_elem_index_get(loop->v)]; - BMFace *efa = loop->f; - vert->nor.w = BM_elem_flag_test(efa, BM_ELEM_HIDDEN) ? -1 : 0; + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + PosNorLoop *vert = &data->vbo_data[l_index]; + copy_v3_v3(vert->pos, bm_vert_co_get(mr, l->v)); + vert->nor = data->packed_nor[BM_elem_index_get(l->v)]; + BMFace *efa = l->f; + vert->nor.w = BM_elem_flag_test(efa, BM_ELEM_HIDDEN) ? -1 : 0; + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); } -static void extract_pos_nor_loop_mesh(const MeshRenderData *mr, - int l, - const MLoop *mloop, - int UNUSED(p), - const MPoly *mpoly, - void *_data) +static void extract_pos_nor_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *_data) { MeshExtract_PosNor_Data *data = _data; - PosNorLoop *vert = data->vbo_data + l; - const MVert *mvert = &mr->mvert[mloop->v]; - copy_v3_v3(vert->pos, mvert->co); - vert->nor = data->packed_nor[mloop->v]; - /* Flag for paint mode overlay. */ - if (mpoly->flag & ME_HIDE || mvert->flag & ME_HIDE || - ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->v_origindex) && - (mr->v_origindex[mloop->v] == ORIGINDEX_NONE))) { - vert->nor.w = -1; - } - else if (mvert->flag & SELECT) { - vert->nor.w = 1; - } - else { - vert->nor.w = 0; + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + PosNorLoop *vert = &data->vbo_data[ml_index]; + const MVert *mv = &mr->mvert[ml->v]; + copy_v3_v3(vert->pos, mv->co); + vert->nor = data->packed_nor[ml->v]; + /* Flag for paint mode overlay. */ + if (mp->flag & ME_HIDE || mv->flag & ME_HIDE || + ((mr->extract_type == MR_EXTRACT_MAPPED) && (mr->v_origindex) && + (mr->v_origindex[ml->v] == ORIGINDEX_NONE))) { + vert->nor.w = -1; + } + else if (mv->flag & SELECT) { + vert->nor.w = 1; + } + else { + vert->nor.w = 0; + } } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } -static void extract_pos_nor_ledge_bmesh(const MeshRenderData *mr, int e, BMEdge *eed, void *_data) +static void extract_pos_nor_iter_ledge_bm(const MeshRenderData *mr, + const ExtractLEdgeBMesh_Params *params, + void *_data) { - int l = mr->loop_len + e * 2; MeshExtract_PosNor_Data *data = _data; - PosNorLoop *vert = data->vbo_data + l; - copy_v3_v3(vert[0].pos, bm_vert_co_get(mr, eed->v1)); - copy_v3_v3(vert[1].pos, bm_vert_co_get(mr, eed->v2)); - vert[0].nor = data->packed_nor[BM_elem_index_get(eed->v1)]; - vert[1].nor = data->packed_nor[BM_elem_index_get(eed->v2)]; + EXTRACT_LEDGE_FOREACH_BM_BEGIN(eed, ledge_index, params) + { + int l_index = mr->loop_len + ledge_index * 2; + PosNorLoop *vert = &data->vbo_data[l_index]; + copy_v3_v3(vert[0].pos, bm_vert_co_get(mr, eed->v1)); + copy_v3_v3(vert[1].pos, bm_vert_co_get(mr, eed->v2)); + vert[0].nor = data->packed_nor[BM_elem_index_get(eed->v1)]; + vert[1].nor = data->packed_nor[BM_elem_index_get(eed->v2)]; + } + EXTRACT_LEDGE_FOREACH_BM_END; } -static void extract_pos_nor_ledge_mesh(const MeshRenderData *mr, - int e, - const MEdge *medge, - void *_data) +static void extract_pos_nor_iter_ledge_mesh(const MeshRenderData *mr, + const ExtractLEdgeMesh_Params *params, + void *_data) { - int l = mr->loop_len + e * 2; MeshExtract_PosNor_Data *data = _data; - PosNorLoop *vert = data->vbo_data + l; - copy_v3_v3(vert[0].pos, mr->mvert[medge->v1].co); - copy_v3_v3(vert[1].pos, mr->mvert[medge->v2].co); - vert[0].nor = data->packed_nor[medge->v1]; - vert[1].nor = data->packed_nor[medge->v2]; + EXTRACT_LEDGE_FOREACH_MESH_BEGIN(med, ledge_index, params, mr) + { + const int ml_index = mr->loop_len + ledge_index * 2; + PosNorLoop *vert = &data->vbo_data[ml_index]; + copy_v3_v3(vert[0].pos, mr->mvert[med->v1].co); + copy_v3_v3(vert[1].pos, mr->mvert[med->v2].co); + vert[0].nor = data->packed_nor[med->v1]; + vert[1].nor = data->packed_nor[med->v2]; + } + EXTRACT_LEDGE_FOREACH_MESH_END; } -static void extract_pos_nor_lvert_bmesh(const MeshRenderData *mr, int v, BMVert *eve, void *_data) +static void extract_pos_nor_iter_lvert_bm(const MeshRenderData *mr, + const ExtractLVertBMesh_Params *params, + void *_data) { - int l = mr->loop_len + mr->edge_loose_len * 2 + v; MeshExtract_PosNor_Data *data = _data; - PosNorLoop *vert = data->vbo_data + l; - copy_v3_v3(vert->pos, bm_vert_co_get(mr, eve)); - vert->nor = data->packed_nor[BM_elem_index_get(eve)]; + const int offset = mr->loop_len + (mr->edge_loose_len * 2); + EXTRACT_LVERT_FOREACH_BM_BEGIN(eve, lvert_index, params) + { + const int l_index = offset + lvert_index; + PosNorLoop *vert = &data->vbo_data[l_index]; + copy_v3_v3(vert->pos, bm_vert_co_get(mr, eve)); + vert->nor = data->packed_nor[BM_elem_index_get(eve)]; + } + EXTRACT_LVERT_FOREACH_BM_END; } -static void extract_pos_nor_lvert_mesh(const MeshRenderData *mr, - int v, - const MVert *mvert, - void *_data) +static void extract_pos_nor_iter_lvert_mesh(const MeshRenderData *mr, + const ExtractLVertMesh_Params *params, + void *_data) { - int l = mr->loop_len + mr->edge_loose_len * 2 + v; - int v_idx = mr->lverts[v]; MeshExtract_PosNor_Data *data = _data; - PosNorLoop *vert = data->vbo_data + l; - copy_v3_v3(vert->pos, mvert->co); - vert->nor = data->packed_nor[v_idx]; + const int offset = mr->loop_len + (mr->edge_loose_len * 2); + EXTRACT_LVERT_FOREACH_MESH_BEGIN(mv, lvert_index, params, mr) + { + const int ml_index = offset + lvert_index; + const int v_index = mr->lverts[lvert_index]; + PosNorLoop *vert = &data->vbo_data[ml_index]; + copy_v3_v3(vert->pos, mv->co); + vert->nor = data->packed_nor[v_index]; + } + EXTRACT_LVERT_FOREACH_MESH_END; } static void extract_pos_nor_finish(const MeshRenderData *UNUSED(mr), void *UNUSED(vbo), void *data) @@ -1633,12 +1998,12 @@ static void extract_pos_nor_finish(const MeshRenderData *UNUSED(mr), void *UNUSE static const MeshExtract extract_pos_nor = { .init = extract_pos_nor_init, - .iter_loop_bm = extract_pos_nor_loop_bmesh, - .iter_loop_mesh = extract_pos_nor_loop_mesh, - .iter_ledge_bm = extract_pos_nor_ledge_bmesh, - .iter_ledge_mesh = extract_pos_nor_ledge_mesh, - .iter_lvert_bm = extract_pos_nor_lvert_bmesh, - .iter_lvert_mesh = extract_pos_nor_lvert_mesh, + .iter_poly_bm = extract_pos_nor_iter_poly_bm, + .iter_poly_mesh = extract_pos_nor_iter_poly_mesh, + .iter_ledge_bm = extract_pos_nor_iter_ledge_bm, + .iter_ledge_mesh = extract_pos_nor_iter_ledge_mesh, + .iter_lvert_bm = extract_pos_nor_iter_lvert_bm, + .iter_lvert_mesh = extract_pos_nor_iter_lvert_mesh, .finish = extract_pos_nor_finish, .data_flag = 0, .use_threading = true, @@ -1667,53 +2032,69 @@ static void *extract_lnor_hq_init(const MeshRenderData *mr, void *buf) return vbo->data; } -static void extract_lnor_hq_loop_bmesh(const MeshRenderData *mr, int l, BMLoop *loop, void *data) +static void extract_lnor_hq_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *data) { if (mr->loop_normals) { - normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, mr->loop_normals[l]); - } - else if (BM_elem_flag_test(loop->f, BM_ELEM_SMOOTH)) { - normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, bm_vert_no_get(mr, loop->v)); + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(_l, l_index, params, mr) + { + normal_float_to_short_v3(&((gpuHQNor *)data)[l_index].x, mr->loop_normals[l_index]); + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(_l); } else { - normal_float_to_short_v3(&((gpuHQNor *)data)[l].x, bm_face_no_get(mr, loop->f)); + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + if (BM_elem_flag_test(l->f, BM_ELEM_SMOOTH)) { + normal_float_to_short_v3(&((gpuHQNor *)data)[l_index].x, bm_vert_no_get(mr, l->v)); + } + else { + normal_float_to_short_v3(&((gpuHQNor *)data)[l_index].x, bm_face_no_get(mr, l->f)); + } + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); } } -static void extract_lnor_hq_loop_mesh( - const MeshRenderData *mr, int l, const MLoop *mloop, int p, const MPoly *mpoly, void *data) +static void extract_lnor_hq_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *data) { - gpuHQNor *lnor_data = &((gpuHQNor *)data)[l]; - if (mr->loop_normals) { - normal_float_to_short_v3(&lnor_data->x, mr->loop_normals[l]); - } - else if (mpoly->flag & ME_SMOOTH) { - copy_v3_v3_short(&lnor_data->x, mr->mvert[mloop->v].no); - } - else { - normal_float_to_short_v3(&lnor_data->x, mr->poly_normals[p]); - } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + gpuHQNor *lnor_data = &((gpuHQNor *)data)[ml_index]; + if (mr->loop_normals) { + normal_float_to_short_v3(&lnor_data->x, mr->loop_normals[ml_index]); + } + else if (mp->flag & ME_SMOOTH) { + copy_v3_v3_short(&lnor_data->x, mr->mvert[ml->v].no); + } + else { + normal_float_to_short_v3(&lnor_data->x, mr->poly_normals[mp_index]); + } - /* Flag for paint mode overlay. - * Only use #MR_EXTRACT_MAPPED in edit mode where it is used to display the edge-normals. - * In paint mode it will use the un-mapped data to draw the wire-frame. */ - if (mpoly->flag & ME_HIDE || - (mr->edit_bmesh && mr->extract_type == MR_EXTRACT_MAPPED && (mr->v_origindex) && - mr->v_origindex[mloop->v] == ORIGINDEX_NONE)) { - lnor_data->w = -1; - } - else if (mpoly->flag & ME_FACE_SEL) { - lnor_data->w = 1; - } - else { - lnor_data->w = 0; + /* Flag for paint mode overlay. + * Only use #MR_EXTRACT_MAPPED in edit mode where it is used to display the edge-normals. + * In paint mode it will use the un-mapped data to draw the wire-frame. */ + if (mp->flag & ME_HIDE || (mr->edit_bmesh && mr->extract_type == MR_EXTRACT_MAPPED && + (mr->v_origindex) && mr->v_origindex[ml->v] == ORIGINDEX_NONE)) { + lnor_data->w = -1; + } + else if (mp->flag & ME_FACE_SEL) { + lnor_data->w = 1; + } + else { + lnor_data->w = 0; + } } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } static const MeshExtract extract_lnor_hq = { .init = extract_lnor_hq_init, - .iter_loop_bm = extract_lnor_hq_loop_bmesh, - .iter_loop_mesh = extract_lnor_hq_loop_mesh, + .iter_poly_bm = extract_lnor_hq_iter_poly_bm, + .iter_poly_mesh = extract_lnor_hq_iter_poly_mesh, .data_flag = MR_DATA_LOOP_NOR, .use_threading = true, }; @@ -1737,55 +2118,73 @@ static void *extract_lnor_init(const MeshRenderData *mr, void *buf) return vbo->data; } -static void extract_lnor_loop_bmesh(const MeshRenderData *mr, int l, BMLoop *loop, void *data) +static void extract_lnor_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *data) { if (mr->loop_normals) { - ((GPUPackedNormal *)data)[l] = GPU_normal_convert_i10_v3(mr->loop_normals[l]); - } - else if (BM_elem_flag_test(loop->f, BM_ELEM_SMOOTH)) { - ((GPUPackedNormal *)data)[l] = GPU_normal_convert_i10_v3(bm_vert_no_get(mr, loop->v)); + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + ((GPUPackedNormal *)data)[l_index] = GPU_normal_convert_i10_v3(mr->loop_normals[l_index]); + BMFace *efa = l->f; + ((GPUPackedNormal *)data)[l_index].w = BM_elem_flag_test(efa, BM_ELEM_HIDDEN) ? -1 : 0; + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); } else { - ((GPUPackedNormal *)data)[l] = GPU_normal_convert_i10_v3(bm_face_no_get(mr, loop->f)); + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + if (BM_elem_flag_test(l->f, BM_ELEM_SMOOTH)) { + ((GPUPackedNormal *)data)[l_index] = GPU_normal_convert_i10_v3(bm_vert_no_get(mr, l->v)); + } + else { + ((GPUPackedNormal *)data)[l_index] = GPU_normal_convert_i10_v3(bm_face_no_get(mr, l->f)); + } + BMFace *efa = l->f; + ((GPUPackedNormal *)data)[l_index].w = BM_elem_flag_test(efa, BM_ELEM_HIDDEN) ? -1 : 0; + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); } - BMFace *efa = loop->f; - ((GPUPackedNormal *)data)[l].w = BM_elem_flag_test(efa, BM_ELEM_HIDDEN) ? -1 : 0; } -static void extract_lnor_loop_mesh( - const MeshRenderData *mr, int l, const MLoop *mloop, int p, const MPoly *mpoly, void *data) +static void extract_lnor_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *data) { - GPUPackedNormal *lnor_data = &((GPUPackedNormal *)data)[l]; - if (mr->loop_normals) { - *lnor_data = GPU_normal_convert_i10_v3(mr->loop_normals[l]); - } - else if (mpoly->flag & ME_SMOOTH) { - *lnor_data = GPU_normal_convert_i10_s3(mr->mvert[mloop->v].no); - } - else { - *lnor_data = GPU_normal_convert_i10_v3(mr->poly_normals[p]); - } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + GPUPackedNormal *lnor_data = &((GPUPackedNormal *)data)[ml_index]; + if (mr->loop_normals) { + *lnor_data = GPU_normal_convert_i10_v3(mr->loop_normals[ml_index]); + } + else if (mp->flag & ME_SMOOTH) { + *lnor_data = GPU_normal_convert_i10_s3(mr->mvert[ml->v].no); + } + else { + *lnor_data = GPU_normal_convert_i10_v3(mr->poly_normals[mp_index]); + } - /* Flag for paint mode overlay. - * Only use MR_EXTRACT_MAPPED in edit mode where it is used to display the edge-normals. - * In paint mode it will use the un-mapped data to draw the wire-frame. */ - if (mpoly->flag & ME_HIDE || - (mr->edit_bmesh && mr->extract_type == MR_EXTRACT_MAPPED && (mr->v_origindex) && - mr->v_origindex[mloop->v] == ORIGINDEX_NONE)) { - lnor_data->w = -1; - } - else if (mpoly->flag & ME_FACE_SEL) { - lnor_data->w = 1; - } - else { - lnor_data->w = 0; + /* Flag for paint mode overlay. + * Only use MR_EXTRACT_MAPPED in edit mode where it is used to display the edge-normals. + * In paint mode it will use the un-mapped data to draw the wire-frame. */ + if (mp->flag & ME_HIDE || (mr->edit_bmesh && mr->extract_type == MR_EXTRACT_MAPPED && + (mr->v_origindex) && mr->v_origindex[ml->v] == ORIGINDEX_NONE)) { + lnor_data->w = -1; + } + else if (mp->flag & ME_FACE_SEL) { + lnor_data->w = 1; + } + else { + lnor_data->w = 0; + } } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } static const MeshExtract extract_lnor = { .init = extract_lnor_init, - .iter_loop_bm = extract_lnor_loop_bmesh, - .iter_loop_mesh = extract_lnor_loop_mesh, + .iter_poly_bm = extract_lnor_iter_poly_bm, + .iter_poly_mesh = extract_lnor_iter_poly_mesh, .data_flag = MR_DATA_LOOP_NOR, .use_threading = true, }; @@ -1871,7 +2270,7 @@ static void *extract_uv_init(const MeshRenderData *mr, void *buf) } else { MLoopUV *layer_data = CustomData_get_layer_n(cd_ldata, CD_MLOOPUV, i); - for (int l = 0; l < mr->loop_len; l++, uv_data++, layer_data++) { + for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, uv_data++, layer_data++) { memcpy(uv_data, layer_data->uv, sizeof(*uv_data)); } } @@ -1946,9 +2345,9 @@ static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool } } else { - const MVert *mvert = mr->mvert; - for (int v = 0; v < mr->vert_len; v++, mvert++) { - copy_v3_v3(orco[v], mvert->co); + const MVert *mv = mr->mvert; + for (int v = 0; v < mr->vert_len; v++, mv++) { + copy_v3_v3(orco[v], mv->co); } } BKE_mesh_orco_verts_transform(mr->me, orco, mr->vert_len, 0); @@ -2023,17 +2422,17 @@ static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool for (int i = 0; i < tan_len; i++) { const char *name = tangent_names[i]; float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named(ldata, CD_TANGENT, name); - for (int l = 0; l < mr->loop_len; l++) { - normal_float_to_short_v3(*tan_data, layer_data[l]); - (*tan_data)[3] = (layer_data[l][3] > 0.0f) ? SHRT_MAX : SHRT_MIN; + for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) { + normal_float_to_short_v3(*tan_data, layer_data[ml_index]); + (*tan_data)[3] = (layer_data[ml_index][3] > 0.0f) ? SHRT_MAX : SHRT_MIN; tan_data++; } } if (use_orco_tan) { float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(ldata, CD_TANGENT, 0); - for (int l = 0; l < mr->loop_len; l++) { - normal_float_to_short_v3(*tan_data, layer_data[l]); - (*tan_data)[3] = (layer_data[l][3] > 0.0f) ? SHRT_MAX : SHRT_MIN; + for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) { + normal_float_to_short_v3(*tan_data, layer_data[ml_index]); + (*tan_data)[3] = (layer_data[ml_index][3] > 0.0f) ? SHRT_MAX : SHRT_MIN; tan_data++; } } @@ -2043,17 +2442,17 @@ static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool for (int i = 0; i < tan_len; i++) { const char *name = tangent_names[i]; float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named(ldata, CD_TANGENT, name); - for (int l = 0; l < mr->loop_len; l++) { - *tan_data = GPU_normal_convert_i10_v3(layer_data[l]); - tan_data->w = (layer_data[l][3] > 0.0f) ? 1 : -2; + for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) { + *tan_data = GPU_normal_convert_i10_v3(layer_data[ml_index]); + tan_data->w = (layer_data[ml_index][3] > 0.0f) ? 1 : -2; tan_data++; } } if (use_orco_tan) { float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(ldata, CD_TANGENT, 0); - for (int l = 0; l < mr->loop_len; l++) { - *tan_data = GPU_normal_convert_i10_v3(layer_data[l]); - tan_data->w = (layer_data[l][3] > 0.0f) ? 1 : -2; + for (int ml_index = 0; ml_index < mr->loop_len; ml_index++) { + *tan_data = GPU_normal_convert_i10_v3(layer_data[ml_index]); + tan_data->w = (layer_data[ml_index][3] > 0.0f) ? 1 : -2; tan_data++; } } @@ -2192,7 +2591,7 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf) } else { const MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer_n(cd_ldata, CD_MLOOPCOL, i); - for (int l = 0; l < mr->loop_len; l++, mloopcol++, vcol_data++) { + for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, mloopcol++, vcol_data++) { vcol_data->r = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mloopcol->r]); vcol_data->g = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mloopcol->g]); vcol_data->b = unit_float_to_ushort_clamp(BLI_color_from_srgb_table[mloopcol->b]); @@ -2221,11 +2620,11 @@ static void *extract_vcol_init(const MeshRenderData *mr, void *buf) } else { MPropCol *vcol = CustomData_get_layer_n(cd_vdata, CD_PROP_COLOR, i); - for (int l = 0; l < mr->loop_len; l++, vcol_data++) { - vcol_data->r = unit_float_to_ushort_clamp(vcol[loops[l].v].color[0]); - vcol_data->g = unit_float_to_ushort_clamp(vcol[loops[l].v].color[1]); - vcol_data->b = unit_float_to_ushort_clamp(vcol[loops[l].v].color[2]); - vcol_data->a = unit_float_to_ushort_clamp(vcol[loops[l].v].color[3]); + for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, vcol_data++) { + vcol_data->r = unit_float_to_ushort_clamp(vcol[loops[ml_index].v].color[0]); + vcol_data->g = unit_float_to_ushort_clamp(vcol[loops[ml_index].v].color[1]); + vcol_data->b = unit_float_to_ushort_clamp(vcol[loops[ml_index].v].color[2]); + vcol_data->a = unit_float_to_ushort_clamp(vcol[loops[ml_index].v].color[3]); } } @@ -2277,28 +2676,32 @@ static void *extract_orco_init(const MeshRenderData *mr, void *buf) return data; } -static void extract_orco_loop_bmesh(const MeshRenderData *UNUSED(mr), - int l, - BMLoop *loop, - void *data) +static void extract_orco_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *data) { MeshExtract_Orco_Data *orco_data = (MeshExtract_Orco_Data *)data; - float *loop_orco = orco_data->vbo_data[l]; - copy_v3_v3(loop_orco, orco_data->orco[BM_elem_index_get(loop->v)]); - loop_orco[3] = 0.0; /* Tag as not a generic attribute. */ + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(loop, l_index, params, mr) + { + float *loop_orco = orco_data->vbo_data[l_index]; + copy_v3_v3(loop_orco, orco_data->orco[BM_elem_index_get(loop->v)]); + loop_orco[3] = 0.0; /* Tag as not a generic attribute. */ + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(loop); } -static void extract_orco_loop_mesh(const MeshRenderData *UNUSED(mr), - int l, - const MLoop *mloop, - int UNUSED(p), - const MPoly *UNUSED(mpoly), - void *data) +static void extract_orco_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *data) { - MeshExtract_Orco_Data *orco_data = (MeshExtract_Orco_Data *)data; - float *loop_orco = orco_data->vbo_data[l]; - copy_v3_v3(loop_orco, orco_data->orco[mloop->v]); - loop_orco[3] = 0.0; /* Tag as not a generic attribute. */ + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + MeshExtract_Orco_Data *orco_data = (MeshExtract_Orco_Data *)data; + float *loop_orco = orco_data->vbo_data[ml_index]; + copy_v3_v3(loop_orco, orco_data->orco[ml->v]); + loop_orco[3] = 0.0; /* Tag as not a generic attribute. */ + } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } static void extract_orco_finish(const MeshRenderData *UNUSED(mr), void *UNUSED(buf), void *data) @@ -2308,8 +2711,8 @@ static void extract_orco_finish(const MeshRenderData *UNUSED(mr), void *UNUSED(b static const MeshExtract extract_orco = { .init = extract_orco_init, - .iter_loop_bm = extract_orco_loop_bmesh, - .iter_loop_mesh = extract_orco_loop_mesh, + .iter_poly_bm = extract_orco_iter_poly_bm, + .iter_poly_mesh = extract_orco_iter_poly_mesh, .finish = extract_orco_finish, .data_flag = 0, .use_threading = true, @@ -2363,9 +2766,9 @@ static void *extract_edge_fac_init(const MeshRenderData *mr, void *buf) /* HACK(fclem) Detecting the need for edge render. * We could have a flag in the mesh instead or check the modifier stack. */ - const MEdge *medge = mr->medge; - for (int e = 0; e < mr->edge_len; e++, medge++) { - if ((medge->flag & ME_EDGERENDER) == 0) { + const MEdge *med = mr->medge; + for (int e_index = 0; e_index < mr->edge_len; e_index++, med++) { + if ((med->flag & ME_EDGERENDER) == 0) { data->use_edge_render = true; break; } @@ -2381,76 +2784,98 @@ static void *extract_edge_fac_init(const MeshRenderData *mr, void *buf) return data; } -static void extract_edge_fac_loop_bmesh(const MeshRenderData *mr, int l, BMLoop *loop, void *_data) +static void extract_edge_fac_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *_data) { - MeshExtract_EdgeFac_Data *data = (MeshExtract_EdgeFac_Data *)_data; - if (BM_edge_is_manifold(loop->e)) { - float ratio = loop_edge_factor_get(bm_face_no_get(mr, loop->f), - bm_vert_co_get(mr, loop->v), - bm_vert_no_get(mr, loop->v), - bm_vert_co_get(mr, loop->next->v)); - data->vbo_data[l] = ratio * 253 + 1; - } - else { - data->vbo_data[l] = 255; + MeshExtract_EdgeFac_Data *data = _data; + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + if (BM_edge_is_manifold(l->e)) { + float ratio = loop_edge_factor_get(bm_face_no_get(mr, l->f), + bm_vert_co_get(mr, l->v), + bm_vert_no_get(mr, l->v), + bm_vert_co_get(mr, l->next->v)); + data->vbo_data[l_index] = ratio * 253 + 1; + } + else { + data->vbo_data[l_index] = 255; + } } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); } -static void extract_edge_fac_loop_mesh( - const MeshRenderData *mr, int l, const MLoop *mloop, int p, const MPoly *mpoly, void *_data) +static void extract_edge_fac_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *_data) { MeshExtract_EdgeFac_Data *data = (MeshExtract_EdgeFac_Data *)_data; + if (data->use_edge_render) { - const MEdge *medge = &mr->medge[mloop->e]; - data->vbo_data[l] = (medge->flag & ME_EDGERENDER) ? 255 : 0; + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + const MEdge *med = &mr->medge[ml->e]; + data->vbo_data[ml_index] = (med->flag & ME_EDGERENDER) ? 255 : 0; + } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } else { - /* Count loop per edge to detect non-manifold. */ - if (data->edge_loop_count[mloop->e] < 3) { - data->edge_loop_count[mloop->e]++; - } - if (data->edge_loop_count[mloop->e] == 2) { - /* Manifold */ - int loopend = mpoly->totloop + mpoly->loopstart - 1; - int other_loop = (l == loopend) ? mpoly->loopstart : (l + 1); - const MLoop *mloop_next = &mr->mloop[other_loop]; - const MVert *v1 = &mr->mvert[mloop->v]; - const MVert *v2 = &mr->mvert[mloop_next->v]; - float vnor_f[3]; - normal_short_to_float_v3(vnor_f, v1->no); - float ratio = loop_edge_factor_get(mr->poly_normals[p], v1->co, vnor_f, v2->co); - data->vbo_data[l] = ratio * 253 + 1; - } - else { - /* Non-manifold */ - data->vbo_data[l] = 255; + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + /* Count loop per edge to detect non-manifold. */ + if (data->edge_loop_count[ml->e] < 3) { + data->edge_loop_count[ml->e]++; + } + if (data->edge_loop_count[ml->e] == 2) { + /* Manifold */ + const int ml_index_last = mp->totloop + mp->loopstart - 1; + const int ml_index_other = (ml_index == ml_index_last) ? mp->loopstart : (ml_index + 1); + const MLoop *ml_next = &mr->mloop[ml_index_other]; + const MVert *v1 = &mr->mvert[ml->v]; + const MVert *v2 = &mr->mvert[ml_next->v]; + float vnor_f[3]; + normal_short_to_float_v3(vnor_f, v1->no); + float ratio = loop_edge_factor_get(mr->poly_normals[mp_index], v1->co, vnor_f, v2->co); + data->vbo_data[ml_index] = ratio * 253 + 1; + } + else { + /* Non-manifold */ + data->vbo_data[ml_index] = 255; + } } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } } -static void extract_edge_fac_ledge_bmesh(const MeshRenderData *mr, - int e, - BMEdge *UNUSED(eed), - void *_data) +static void extract_edge_fac_iter_ledge_bm(const MeshRenderData *mr, + const ExtractLEdgeBMesh_Params *params, + void *_data) { - MeshExtract_EdgeFac_Data *data = (MeshExtract_EdgeFac_Data *)_data; - data->vbo_data[mr->loop_len + e * 2 + 0] = 255; - data->vbo_data[mr->loop_len + e * 2 + 1] = 255; + MeshExtract_EdgeFac_Data *data = _data; + EXTRACT_LEDGE_FOREACH_BM_BEGIN(eed, ledge_index, params) + { + data->vbo_data[mr->loop_len + (ledge_index * 2) + 0] = 255; + data->vbo_data[mr->loop_len + (ledge_index * 2) + 1] = 255; + } + EXTRACT_LEDGE_FOREACH_BM_END; } -static void extract_edge_fac_ledge_mesh(const MeshRenderData *mr, - int e, - const MEdge *UNUSED(edge), - void *_data) +static void extract_edge_fac_iter_ledge_mesh(const MeshRenderData *mr, + const ExtractLEdgeMesh_Params *params, + void *_data) { - MeshExtract_EdgeFac_Data *data = (MeshExtract_EdgeFac_Data *)_data; - data->vbo_data[mr->loop_len + e * 2 + 0] = 255; - data->vbo_data[mr->loop_len + e * 2 + 1] = 255; + MeshExtract_EdgeFac_Data *data = _data; + EXTRACT_LEDGE_FOREACH_MESH_BEGIN(med, ledge_index, params, mr) + { + data->vbo_data[mr->loop_len + ledge_index * 2 + 0] = 255; + data->vbo_data[mr->loop_len + ledge_index * 2 + 1] = 255; + } + EXTRACT_LEDGE_FOREACH_MESH_END; } static void extract_edge_fac_finish(const MeshRenderData *mr, void *buf, void *_data) { - MeshExtract_EdgeFac_Data *data = (MeshExtract_EdgeFac_Data *)_data; + MeshExtract_EdgeFac_Data *data = _data; if (GPU_crappy_amd_driver()) { GPUVertBuf *vbo = (GPUVertBuf *)buf; @@ -2470,8 +2895,8 @@ static void extract_edge_fac_finish(const MeshRenderData *mr, void *buf, void *_ GPU_vertbuf_data_alloc(vbo, buf_len); float *fdata = (float *)vbo->data; - for (int l = 0; l < buf_len; l++, fdata++) { - *fdata = data->vbo_data[l] / 255.0f; + for (int ml_index = 0; ml_index < buf_len; ml_index++, fdata++) { + *fdata = data->vbo_data[ml_index] / 255.0f; } /* Free old byte data. */ MEM_freeN(data->vbo_data); @@ -2481,10 +2906,10 @@ static void extract_edge_fac_finish(const MeshRenderData *mr, void *buf, void *_ static const MeshExtract extract_edge_fac = { .init = extract_edge_fac_init, - .iter_loop_bm = extract_edge_fac_loop_bmesh, - .iter_loop_mesh = extract_edge_fac_loop_mesh, - .iter_ledge_bm = extract_edge_fac_ledge_bmesh, - .iter_ledge_mesh = extract_edge_fac_ledge_mesh, + .iter_poly_bm = extract_edge_fac_iter_poly_bm, + .iter_poly_mesh = extract_edge_fac_iter_poly_mesh, + .iter_ledge_bm = extract_edge_fac_iter_ledge_bm, + .iter_ledge_mesh = extract_edge_fac_iter_ledge_mesh, .finish = extract_edge_fac_finish, .data_flag = MR_DATA_POLY_NOR, .use_threading = false, @@ -2585,27 +3010,49 @@ static void *extract_weights_init(const MeshRenderData *mr, void *buf) return data; } -static void extract_weights_loop_bmesh(const MeshRenderData *UNUSED(mr), - int l, - BMLoop *loop, - void *_data) +static void extract_weights_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *_data) { - MeshExtract_Weight_Data *data = (MeshExtract_Weight_Data *)_data; - const MDeformVert *dvert = (data->cd_ofs != -1) ? BM_ELEM_CD_GET_VOID_P(loop->v, data->cd_ofs) : - NULL; - data->vbo_data[l] = evaluate_vertex_weight(dvert, data->wstate); + MeshExtract_Weight_Data *data = _data; + if (data->cd_ofs != -1) { + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + const MDeformVert *dvert = BM_ELEM_CD_GET_VOID_P(l->v, data->cd_ofs); + data->vbo_data[l_index] = evaluate_vertex_weight(dvert, data->wstate); + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); + } + else { + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + data->vbo_data[l_index] = evaluate_vertex_weight(NULL, data->wstate); + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); + } } -static void extract_weights_loop_mesh(const MeshRenderData *UNUSED(mr), - int l, - const MLoop *mloop, - int UNUSED(p), - const MPoly *UNUSED(mpoly), - void *_data) +static void extract_weights_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *_data) { - MeshExtract_Weight_Data *data = (MeshExtract_Weight_Data *)_data; - const MDeformVert *dvert = data->dvert ? &data->dvert[mloop->v] : NULL; - data->vbo_data[l] = evaluate_vertex_weight(dvert, data->wstate); + MeshExtract_Weight_Data *data = _data; + if (data->dvert != NULL) { + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + const MDeformVert *dvert = &data->dvert[ml->v]; + data->vbo_data[ml_index] = evaluate_vertex_weight(dvert, data->wstate); + } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; + } + else { + const MDeformVert *dvert = NULL; + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + data->vbo_data[ml_index] = evaluate_vertex_weight(dvert, data->wstate); + } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; + } } static void extract_weights_finish(const MeshRenderData *UNUSED(mr), void *UNUSED(buf), void *data) @@ -2615,8 +3062,8 @@ static void extract_weights_finish(const MeshRenderData *UNUSED(mr), void *UNUSE static const MeshExtract extract_weights = { .init = extract_weights_init, - .iter_loop_bm = extract_weights_loop_bmesh, - .iter_loop_mesh = extract_weights_loop_mesh, + .iter_poly_bm = extract_weights_iter_poly_bm, + .iter_poly_mesh = extract_weights_iter_poly_mesh, .finish = extract_weights_finish, .data_flag = 0, .use_threading = true, @@ -2726,31 +3173,31 @@ static void mesh_render_data_edge_flag(const MeshRenderData *mr, BMEdge *eed, Ed } static void mesh_render_data_loop_flag(const MeshRenderData *mr, - BMLoop *loop, + BMLoop *l, const int cd_ofs, EditLoopData *eattr) { if (cd_ofs == -1) { return; } - MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, cd_ofs); + MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_ofs); if (luv != NULL && (luv->flag & MLOOPUV_PINNED)) { eattr->v_flag |= VFLAG_VERT_UV_PINNED; } - if (uvedit_uv_select_test_ex(mr->toolsettings, loop, cd_ofs)) { + if (uvedit_uv_select_test_ex(mr->toolsettings, l, cd_ofs)) { eattr->v_flag |= VFLAG_VERT_UV_SELECT; } } static void mesh_render_data_loop_edge_flag(const MeshRenderData *mr, - BMLoop *loop, + BMLoop *l, const int cd_ofs, EditLoopData *eattr) { if (cd_ofs == -1) { return; } - if (uvedit_edge_select_test_ex(mr->toolsettings, loop, cd_ofs)) { + if (uvedit_edge_select_test_ex(mr->toolsettings, l, cd_ofs)) { eattr->v_flag |= VFLAG_EDGE_UV_SELECT; eattr->v_flag |= VFLAG_VERT_UV_SELECT; } @@ -2780,109 +3227,128 @@ static void *extract_edit_data_init(const MeshRenderData *mr, void *buf) return vbo->data; } -static void extract_edit_data_loop_bmesh(const MeshRenderData *mr, - int l, - BMLoop *loop, - void *_data) +static void extract_edit_data_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *_data) { - EditLoopData *data = (EditLoopData *)_data + l; - memset(data, 0x0, sizeof(*data)); - mesh_render_data_face_flag(mr, loop->f, -1, data); - mesh_render_data_edge_flag(mr, loop->e, data); - mesh_render_data_vert_flag(mr, loop->v, data); -} -static void extract_edit_data_loop_mesh(const MeshRenderData *mr, - int l, - const MLoop *mloop, - int p, - const MPoly *UNUSED(mpoly), - void *_data) -{ - EditLoopData *data = (EditLoopData *)_data + l; - memset(data, 0x0, sizeof(*data)); - BMFace *efa = bm_original_face_get(mr, p); - BMEdge *eed = bm_original_edge_get(mr, mloop->e); - BMVert *eve = bm_original_vert_get(mr, mloop->v); - if (efa) { - mesh_render_data_face_flag(mr, efa, -1, data); - } - if (eed) { - mesh_render_data_edge_flag(mr, eed, data); - } - if (eve) { - mesh_render_data_vert_flag(mr, eve, data); + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + EditLoopData *data = (EditLoopData *)_data + l_index; + memset(data, 0x0, sizeof(*data)); + mesh_render_data_face_flag(mr, l->f, -1, data); + mesh_render_data_edge_flag(mr, l->e, data); + mesh_render_data_vert_flag(mr, l->v, data); } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); } -static void extract_edit_data_ledge_bmesh(const MeshRenderData *mr, - int e, - BMEdge *eed, - void *_data) +static void extract_edit_data_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *_data) { - EditLoopData *data = (EditLoopData *)_data + mr->loop_len + e * 2; - memset(data, 0x0, sizeof(*data) * 2); - mesh_render_data_edge_flag(mr, eed, &data[0]); - data[1] = data[0]; - mesh_render_data_vert_flag(mr, eed->v1, &data[0]); - mesh_render_data_vert_flag(mr, eed->v2, &data[1]); + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + EditLoopData *data = (EditLoopData *)_data + ml_index; + memset(data, 0x0, sizeof(*data)); + BMFace *efa = bm_original_face_get(mr, mp_index); + BMEdge *eed = bm_original_edge_get(mr, ml->e); + BMVert *eve = bm_original_vert_get(mr, ml->v); + if (efa) { + mesh_render_data_face_flag(mr, efa, -1, data); + } + if (eed) { + mesh_render_data_edge_flag(mr, eed, data); + } + if (eve) { + mesh_render_data_vert_flag(mr, eve, data); + } + } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } -static void extract_edit_data_ledge_mesh(const MeshRenderData *mr, - int e, - const MEdge *edge, - void *_data) +static void extract_edit_data_iter_ledge_bm(const MeshRenderData *mr, + const ExtractLEdgeBMesh_Params *params, + void *_data) { - EditLoopData *data = (EditLoopData *)_data + mr->loop_len + e * 2; - memset(data, 0x0, sizeof(*data) * 2); - int e_idx = mr->ledges[e]; - BMEdge *eed = bm_original_edge_get(mr, e_idx); - BMVert *eve1 = bm_original_vert_get(mr, edge->v1); - BMVert *eve2 = bm_original_vert_get(mr, edge->v2); - if (eed) { + EXTRACT_LEDGE_FOREACH_BM_BEGIN(eed, ledge_index, params) + { + EditLoopData *data = (EditLoopData *)_data + mr->loop_len + (ledge_index * 2); + memset(data, 0x0, sizeof(*data) * 2); mesh_render_data_edge_flag(mr, eed, &data[0]); data[1] = data[0]; + mesh_render_data_vert_flag(mr, eed->v1, &data[0]); + mesh_render_data_vert_flag(mr, eed->v2, &data[1]); + } + EXTRACT_LEDGE_FOREACH_BM_END; +} + +static void extract_edit_data_iter_ledge_mesh(const MeshRenderData *mr, + const ExtractLEdgeMesh_Params *params, + void *_data) +{ + EXTRACT_LEDGE_FOREACH_MESH_BEGIN(med, ledge_index, params, mr) + { + EditLoopData *data = (EditLoopData *)_data + mr->loop_len + ledge_index * 2; + memset(data, 0x0, sizeof(*data) * 2); + const int e_index = mr->ledges[ledge_index]; + BMEdge *eed = bm_original_edge_get(mr, e_index); + BMVert *eve1 = bm_original_vert_get(mr, med->v1); + BMVert *eve2 = bm_original_vert_get(mr, med->v2); + if (eed) { + mesh_render_data_edge_flag(mr, eed, &data[0]); + data[1] = data[0]; + } + if (eve1) { + mesh_render_data_vert_flag(mr, eve1, &data[0]); + } + if (eve2) { + mesh_render_data_vert_flag(mr, eve2, &data[1]); + } } - if (eve1) { - mesh_render_data_vert_flag(mr, eve1, &data[0]); - } - if (eve2) { - mesh_render_data_vert_flag(mr, eve2, &data[1]); - } + EXTRACT_LEDGE_FOREACH_MESH_END; } -static void extract_edit_data_lvert_bmesh(const MeshRenderData *mr, - int v, - BMVert *eve, - void *_data) +static void extract_edit_data_iter_lvert_bm(const MeshRenderData *mr, + const ExtractLVertBMesh_Params *params, + void *_data) { - EditLoopData *data = (EditLoopData *)_data + mr->loop_len + mr->edge_loose_len * 2 + v; - memset(data, 0x0, sizeof(*data)); - mesh_render_data_vert_flag(mr, eve, data); + const int offset = mr->loop_len + (mr->edge_loose_len * 2); + EXTRACT_LVERT_FOREACH_BM_BEGIN(eve, lvert_index, params) + { + EditLoopData *data = (EditLoopData *)_data + offset + lvert_index; + memset(data, 0x0, sizeof(*data)); + mesh_render_data_vert_flag(mr, eve, data); + } + EXTRACT_LVERT_FOREACH_BM_END; } -static void extract_edit_data_lvert_mesh(const MeshRenderData *mr, - int v, - const MVert *UNUSED(mvert), - void *_data) +static void extract_edit_data_iter_lvert_mesh(const MeshRenderData *mr, + const ExtractLVertMesh_Params *params, + void *_data) { - EditLoopData *data = (EditLoopData *)_data + mr->loop_len + mr->edge_loose_len * 2 + v; - memset(data, 0x0, sizeof(*data)); - int v_idx = mr->lverts[v]; - BMVert *eve = bm_original_vert_get(mr, v_idx); - if (eve) { - mesh_render_data_vert_flag(mr, eve, data); + const int offset = mr->loop_len + (mr->edge_loose_len * 2); + EXTRACT_LVERT_FOREACH_MESH_BEGIN(mv, lvert_index, params, mr) + { + EditLoopData *data = (EditLoopData *)_data + offset + lvert_index; + memset(data, 0x0, sizeof(*data)); + const int v_index = mr->lverts[lvert_index]; + BMVert *eve = bm_original_vert_get(mr, v_index); + if (eve) { + mesh_render_data_vert_flag(mr, eve, data); + } } + EXTRACT_LVERT_FOREACH_MESH_END; } static const MeshExtract extract_edit_data = { .init = extract_edit_data_init, - .iter_loop_bm = extract_edit_data_loop_bmesh, - .iter_loop_mesh = extract_edit_data_loop_mesh, - .iter_ledge_bm = extract_edit_data_ledge_bmesh, - .iter_ledge_mesh = extract_edit_data_ledge_mesh, - .iter_lvert_bm = extract_edit_data_lvert_bmesh, - .iter_lvert_mesh = extract_edit_data_lvert_mesh, + .iter_poly_bm = extract_edit_data_iter_poly_bm, + .iter_poly_mesh = extract_edit_data_iter_poly_mesh, + .iter_ledge_bm = extract_edit_data_iter_ledge_bm, + .iter_ledge_mesh = extract_edit_data_iter_ledge_mesh, + .iter_lvert_bm = extract_edit_data_iter_lvert_bm, + .iter_lvert_mesh = extract_edit_data_iter_lvert_mesh, .data_flag = 0, .use_threading = true, }; @@ -2919,51 +3385,59 @@ static void *extract_edituv_data_init(const MeshRenderData *mr, void *buf) return data; } -static void extract_edituv_data_loop_bmesh(const MeshRenderData *mr, - int l, - BMLoop *loop, - void *_data) +static void extract_edituv_data_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *_data) { - MeshExtract_EditUVData_Data *data = (MeshExtract_EditUVData_Data *)_data; - EditLoopData *eldata = data->vbo_data + l; - memset(eldata, 0x0, sizeof(*eldata)); - mesh_render_data_loop_flag(mr, loop, data->cd_ofs, eldata); - mesh_render_data_face_flag(mr, loop->f, data->cd_ofs, eldata); - mesh_render_data_loop_edge_flag(mr, loop, data->cd_ofs, eldata); -} - -static void extract_edituv_data_loop_mesh( - const MeshRenderData *mr, int l, const MLoop *mloop, int p, const MPoly *mpoly, void *_data) -{ - MeshExtract_EditUVData_Data *data = (MeshExtract_EditUVData_Data *)_data; - EditLoopData *eldata = data->vbo_data + l; - memset(eldata, 0x0, sizeof(*eldata)); - BMFace *efa = bm_original_face_get(mr, p); - if (efa) { - BMEdge *eed = bm_original_edge_get(mr, mloop->e); - BMVert *eve = bm_original_vert_get(mr, mloop->v); - if (eed && eve) { - /* Loop on an edge endpoint. */ - BMLoop *loop = BM_face_edge_share_loop(efa, eed); - mesh_render_data_loop_flag(mr, loop, data->cd_ofs, eldata); - mesh_render_data_loop_edge_flag(mr, loop, data->cd_ofs, eldata); - } - else { - if (eed == NULL) { - /* Find if the loop's vert is not part of an edit edge. - * For this, we check if the previous loop was on an edge. */ - int loopend = mpoly->loopstart + mpoly->totloop - 1; - int l_prev = (l == mpoly->loopstart) ? loopend : (l - 1); - const MLoop *mloop_prev = &mr->mloop[l_prev]; - eed = bm_original_edge_get(mr, mloop_prev->e); + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + MeshExtract_EditUVData_Data *data = _data; + EditLoopData *eldata = &data->vbo_data[l_index]; + memset(eldata, 0x0, sizeof(*eldata)); + mesh_render_data_loop_flag(mr, l, data->cd_ofs, eldata); + mesh_render_data_face_flag(mr, l->f, data->cd_ofs, eldata); + mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, eldata); + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); +} + +static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *_data) +{ + MeshExtract_EditUVData_Data *data = _data; + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + EditLoopData *eldata = &data->vbo_data[ml_index]; + memset(eldata, 0x0, sizeof(*eldata)); + BMFace *efa = bm_original_face_get(mr, mp_index); + if (efa) { + BMEdge *eed = bm_original_edge_get(mr, ml->e); + BMVert *eve = bm_original_vert_get(mr, ml->v); + if (eed && eve) { + /* Loop on an edge endpoint. */ + BMLoop *l = BM_face_edge_share_loop(efa, eed); + mesh_render_data_loop_flag(mr, l, data->cd_ofs, eldata); + mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, eldata); } - if (eed) { - /* Mapped points on an edge between two edit verts. */ - BMLoop *loop = BM_face_edge_share_loop(efa, eed); - mesh_render_data_loop_edge_flag(mr, loop, data->cd_ofs, eldata); + else { + if (eed == NULL) { + /* Find if the loop's vert is not part of an edit edge. + * For this, we check if the previous loop was on an edge. */ + const int ml_index_last = mp->loopstart + mp->totloop - 1; + const int l_prev = (ml_index == mp->loopstart) ? ml_index_last : (ml_index - 1); + const MLoop *ml_prev = &mr->mloop[l_prev]; + eed = bm_original_edge_get(mr, ml_prev->e); + } + if (eed) { + /* Mapped points on an edge between two edit verts. */ + BMLoop *l = BM_face_edge_share_loop(efa, eed); + mesh_render_data_loop_edge_flag(mr, l, data->cd_ofs, eldata); + } } } } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } static void extract_edituv_data_finish(const MeshRenderData *UNUSED(mr), @@ -2975,8 +3449,8 @@ static void extract_edituv_data_finish(const MeshRenderData *UNUSED(mr), static const MeshExtract extract_edituv_data = { .init = extract_edituv_data_init, - .iter_loop_bm = extract_edituv_data_loop_bmesh, - .iter_loop_mesh = extract_edituv_data_loop_mesh, + .iter_poly_bm = extract_edituv_data_iter_poly_bm, + .iter_poly_mesh = extract_edituv_data_iter_poly_mesh, .finish = extract_edituv_data_finish, .data_flag = 0, .use_threading = true, @@ -3039,13 +3513,13 @@ static void mesh_stretch_area_finish(const MeshRenderData *mr, void *buf, void * } else if (mr->extract_type == MR_EXTRACT_MAPPED) { const MLoopUV *uv_data = CustomData_get_layer(&mr->me->ldata, CD_MLOOPUV); - const MPoly *mpoly = mr->mpoly; - for (int p = 0; p < mr->poly_len; p++, mpoly++) { - float area = BKE_mesh_calc_poly_area(mpoly, &mr->mloop[mpoly->loopstart], mr->mvert); - float uvarea = BKE_mesh_calc_poly_uv_area(mpoly, uv_data); + const MPoly *mp = mr->mpoly; + for (int mp_index = 0; mp_index < mr->poly_len; mp_index++, mp++) { + float area = BKE_mesh_calc_poly_area(mp, &mr->mloop[mp->loopstart], mr->mvert); + float uvarea = BKE_mesh_calc_poly_uv_area(mp, uv_data); tot_area += area; tot_uv_area += uvarea; - area_ratio[p] = area_ratio_get(area, uvarea); + area_ratio[mp_index] = area_ratio_get(area, uvarea); } } else { @@ -3058,8 +3532,8 @@ static void mesh_stretch_area_finish(const MeshRenderData *mr, void *buf, void * /* Convert in place to avoid an extra allocation */ uint16_t *poly_stretch = (uint16_t *)area_ratio; - for (int p = 0; p < mr->poly_len; p++) { - poly_stretch[p] = area_ratio[p] * SHRT_MAX; + for (int mp_index = 0; mp_index < mr->poly_len; mp_index++) { + poly_stretch[mp_index] = area_ratio[mp_index] * SHRT_MAX; } /* Copy face data for each loop. */ @@ -3069,18 +3543,18 @@ static void mesh_stretch_area_finish(const MeshRenderData *mr, void *buf, void * if (mr->extract_type == MR_EXTRACT_BMESH) { BMFace *efa; BMIter f_iter; - int f, l = 0; + int f, l_index = 0; BM_ITER_MESH_INDEX (efa, &f_iter, mr->bm, BM_FACES_OF_MESH, f) { - for (int i = 0; i < efa->len; i++, l++) { - loop_stretch[l] = poly_stretch[f]; + for (int i = 0; i < efa->len; i++, l_index++) { + loop_stretch[l_index] = poly_stretch[f]; } } } else if (mr->extract_type == MR_EXTRACT_MAPPED) { - const MPoly *mpoly = mr->mpoly; - for (int p = 0, l = 0; p < mr->poly_len; p++, mpoly++) { - for (int i = 0; i < mpoly->totloop; i++, l++) { - loop_stretch[l] = poly_stretch[p]; + const MPoly *mp = mr->mpoly; + for (int mp_index = 0, l_index = 0; mp_index < mr->poly_len; mp_index++, mp++) { + for (int i = 0; i < mp->totloop; i++, l_index++) { + loop_stretch[l_index] = poly_stretch[mp_index]; } } } @@ -3186,94 +3660,95 @@ static void *extract_stretch_angle_init(const MeshRenderData *mr, void *buf) return data; } -static void extract_stretch_angle_loop_bmesh(const MeshRenderData *mr, - int l, - BMLoop *loop, - void *_data) +static void extract_stretch_angle_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *_data) { - MeshExtract_StretchAngle_Data *data = (MeshExtract_StretchAngle_Data *)_data; + MeshExtract_StretchAngle_Data *data = _data; float(*auv)[2] = data->auv, *last_auv = data->last_auv; float(*av)[3] = data->av, *last_av = data->last_av; - const MLoopUV *luv, *luv_next; - BMLoop *l_next = loop->next; - BMFace *efa = loop->f; - if (loop == BM_FACE_FIRST_LOOP(efa)) { - /* First loop in face. */ - BMLoop *l_tmp = loop->prev; - BMLoop *l_next_tmp = loop; - luv = BM_ELEM_CD_GET_VOID_P(l_tmp, data->cd_ofs); - luv_next = BM_ELEM_CD_GET_VOID_P(l_next_tmp, data->cd_ofs); - compute_normalize_edge_vectors(auv, - av, - luv->uv, - luv_next->uv, - bm_vert_co_get(mr, l_tmp->v), - bm_vert_co_get(mr, l_next_tmp->v)); - /* Save last edge. */ - copy_v2_v2(last_auv, auv[1]); - copy_v3_v3(last_av, av[1]); - } - if (l_next == BM_FACE_FIRST_LOOP(efa)) { - /* Move previous edge. */ - copy_v2_v2(auv[0], auv[1]); - copy_v3_v3(av[0], av[1]); - /* Copy already calculated last edge. */ - copy_v2_v2(auv[1], last_auv); - copy_v3_v3(av[1], last_av); + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + const MLoopUV *luv, *luv_next; + BMLoop *l_next = l->next; + BMFace *efa = l->f; + if (l == BM_FACE_FIRST_LOOP(efa)) { + /* First loop in face. */ + BMLoop *l_tmp = l->prev; + BMLoop *l_next_tmp = l; + luv = BM_ELEM_CD_GET_VOID_P(l_tmp, data->cd_ofs); + luv_next = BM_ELEM_CD_GET_VOID_P(l_next_tmp, data->cd_ofs); + compute_normalize_edge_vectors(auv, + av, + luv->uv, + luv_next->uv, + bm_vert_co_get(mr, l_tmp->v), + bm_vert_co_get(mr, l_next_tmp->v)); + /* Save last edge. */ + copy_v2_v2(last_auv, auv[1]); + copy_v3_v3(last_av, av[1]); + } + if (l_next == BM_FACE_FIRST_LOOP(efa)) { + /* Move previous edge. */ + copy_v2_v2(auv[0], auv[1]); + copy_v3_v3(av[0], av[1]); + /* Copy already calculated last edge. */ + copy_v2_v2(auv[1], last_auv); + copy_v3_v3(av[1], last_av); + } + else { + luv = BM_ELEM_CD_GET_VOID_P(l, data->cd_ofs); + luv_next = BM_ELEM_CD_GET_VOID_P(l_next, data->cd_ofs); + compute_normalize_edge_vectors( + auv, av, luv->uv, luv_next->uv, bm_vert_co_get(mr, l->v), bm_vert_co_get(mr, l_next->v)); + } + edituv_get_stretch_angle(auv, av, &data->vbo_data[l_index]); } - else { - luv = BM_ELEM_CD_GET_VOID_P(loop, data->cd_ofs); - luv_next = BM_ELEM_CD_GET_VOID_P(l_next, data->cd_ofs); - compute_normalize_edge_vectors(auv, - av, - luv->uv, - luv_next->uv, - bm_vert_co_get(mr, loop->v), - bm_vert_co_get(mr, l_next->v)); - } - edituv_get_stretch_angle(auv, av, data->vbo_data + l); -} - -static void extract_stretch_angle_loop_mesh(const MeshRenderData *mr, - int l, - const MLoop *UNUSED(mloop), - int UNUSED(p), - const MPoly *mpoly, - void *_data) + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); +} + +static void extract_stretch_angle_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *_data) { - MeshExtract_StretchAngle_Data *data = (MeshExtract_StretchAngle_Data *)_data; - float(*auv)[2] = data->auv, *last_auv = data->last_auv; - float(*av)[3] = data->av, *last_av = data->last_av; - int l_next = l + 1, loopend = mpoly->loopstart + mpoly->totloop; - const MVert *v, *v_next; - if (l == mpoly->loopstart) { - /* First loop in face. */ - int l_tmp = loopend - 1; - int l_next_tmp = mpoly->loopstart; - v = &mr->mvert[mr->mloop[l_tmp].v]; - v_next = &mr->mvert[mr->mloop[l_next_tmp].v]; - compute_normalize_edge_vectors( - auv, av, data->luv[l_tmp].uv, data->luv[l_next_tmp].uv, v->co, v_next->co); - /* Save last edge. */ - copy_v2_v2(last_auv, auv[1]); - copy_v3_v3(last_av, av[1]); - } - if (l_next == loopend) { - l_next = mpoly->loopstart; - /* Move previous edge. */ - copy_v2_v2(auv[0], auv[1]); - copy_v3_v3(av[0], av[1]); - /* Copy already calculated last edge. */ - copy_v2_v2(auv[1], last_auv); - copy_v3_v3(av[1], last_av); - } - else { - v = &mr->mvert[mr->mloop[l].v]; - v_next = &mr->mvert[mr->mloop[l_next].v]; - compute_normalize_edge_vectors( - auv, av, data->luv[l].uv, data->luv[l_next].uv, v->co, v_next->co); + MeshExtract_StretchAngle_Data *data = _data; + + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + float(*auv)[2] = data->auv, *last_auv = data->last_auv; + float(*av)[3] = data->av, *last_av = data->last_av; + int l_next = ml_index + 1, ml_index_end = mp->loopstart + mp->totloop; + const MVert *v, *v_next; + if (ml_index == mp->loopstart) { + /* First loop in face. */ + const int ml_index_last = ml_index_end - 1; + const int l_next_tmp = mp->loopstart; + v = &mr->mvert[mr->mloop[ml_index_last].v]; + v_next = &mr->mvert[mr->mloop[l_next_tmp].v]; + compute_normalize_edge_vectors( + auv, av, data->luv[ml_index_last].uv, data->luv[l_next_tmp].uv, v->co, v_next->co); + /* Save last edge. */ + copy_v2_v2(last_auv, auv[1]); + copy_v3_v3(last_av, av[1]); + } + if (l_next == ml_index_end) { + l_next = mp->loopstart; + /* Move previous edge. */ + copy_v2_v2(auv[0], auv[1]); + copy_v3_v3(av[0], av[1]); + /* Copy already calculated last edge. */ + copy_v2_v2(auv[1], last_auv); + copy_v3_v3(av[1], last_av); + } + else { + v = &mr->mvert[mr->mloop[ml_index].v]; + v_next = &mr->mvert[mr->mloop[l_next].v]; + compute_normalize_edge_vectors( + auv, av, data->luv[ml_index].uv, data->luv[l_next].uv, v->co, v_next->co); + } + edituv_get_stretch_angle(auv, av, &data->vbo_data[ml_index]); } - edituv_get_stretch_angle(auv, av, data->vbo_data + l); + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } static void extract_stretch_angle_finish(const MeshRenderData *UNUSED(mr), @@ -3285,8 +3760,8 @@ static void extract_stretch_angle_finish(const MeshRenderData *UNUSED(mr), static const MeshExtract extract_stretch_angle = { .init = extract_stretch_angle_init, - .iter_loop_bm = extract_stretch_angle_loop_bmesh, - .iter_loop_mesh = extract_stretch_angle_loop_mesh, + .iter_poly_bm = extract_stretch_angle_iter_poly_bm, + .iter_poly_mesh = extract_stretch_angle_iter_poly_mesh, .finish = extract_stretch_angle_finish, .data_flag = 0, .use_threading = false, @@ -3361,22 +3836,22 @@ static void statvis_calc_overhang(const MeshRenderData *mr, float *r_overhang) normalize_v3(dir); if (mr->extract_type == MR_EXTRACT_BMESH) { - int l = 0; + int l_index = 0; BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { float fac = angle_normalized_v3v3(bm_face_no_get(mr, f), dir) / (float)M_PI; fac = overhang_remap(fac, min, max, minmax_irange); - for (int i = 0; i < f->len; i++, l++) { - r_overhang[l] = fac; + for (int i = 0; i < f->len; i++, l_index++) { + r_overhang[l_index] = fac; } } } else { - const MPoly *mpoly = mr->mpoly; - for (int p = 0, l = 0; p < mr->poly_len; p++, mpoly++) { - float fac = angle_normalized_v3v3(mr->poly_normals[p], dir) / (float)M_PI; + const MPoly *mp = mr->mpoly; + for (int mp_index = 0, l_index = 0; mp_index < mr->poly_len; mp_index++, mp++) { + float fac = angle_normalized_v3v3(mr->poly_normals[mp_index], dir) / (float)M_PI; fac = overhang_remap(fac, min, max, minmax_irange); - for (int i = 0; i < mpoly->totloop; i++, l++) { - r_overhang[l] = fac; + for (int i = 0; i < mp->totloop; i++, l_index++) { + r_overhang[l_index] = fac; } } } @@ -3476,12 +3951,12 @@ static void statvis_calc_thickness(const MeshRenderData *mr, float *r_thickness) BMIter iter; BMFace *f; - int l = 0; + int l_index = 0; BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { float fac = face_dists[BM_elem_index_get(f)]; fac = thickness_remap(fac, min, max, minmax_irange); - for (int i = 0; i < f->len; i++, l++) { - r_thickness[l] = fac; + for (int i = 0; i < f->len; i++, l_index++) { + r_thickness[l_index] = fac; } } } @@ -3522,12 +3997,12 @@ static void statvis_calc_thickness(const MeshRenderData *mr, float *r_thickness) } } - const MPoly *mpoly = mr->mpoly; - for (int p = 0, l = 0; p < mr->poly_len; p++, mpoly++) { - float fac = face_dists[p]; + const MPoly *mp = mr->mpoly; + for (int mp_index = 0, l_index = 0; mp_index < mr->poly_len; mp_index++, mp++) { + float fac = face_dists[mp_index]; fac = thickness_remap(fac, min, max, minmax_irange); - for (int i = 0; i < mpoly->totloop; i++, l++) { - r_thickness[l] = fac; + for (int i = 0; i < mp->totloop; i++, l_index++) { + r_thickness[l_index] = fac; } } } @@ -3578,8 +4053,8 @@ static void statvis_calc_intersect(const MeshRenderData *mr, float *r_intersect) { BMEditMesh *em = mr->edit_bmesh; - for (int l = 0; l < mr->loop_len; l++) { - r_intersect[l] = -1.0f; + for (int l_index = 0; l_index < mr->loop_len; l_index++) { + r_intersect[l_index] = -1.0f; } if (mr->extract_type == MR_EXTRACT_BMESH) { @@ -3600,9 +4075,9 @@ static void statvis_calc_intersect(const MeshRenderData *mr, float *r_intersect) for (int j = 0; j < 2; j++) { BMFace *f_hit = f_hit_pair[j]; BMLoop *l_first = BM_FACE_FIRST_LOOP(f_hit); - int l = BM_elem_index_get(l_first); - for (int k = 0; k < f_hit->len; k++, l++) { - r_intersect[l] = 1.0f; + int l_index = BM_elem_index_get(l_first); + for (int k = 0; k < f_hit->len; k++, l_index++) { + r_intersect[l_index] = 1.0f; } } } @@ -3629,9 +4104,9 @@ static void statvis_calc_intersect(const MeshRenderData *mr, float *r_intersect) }; for (int j = 0; j < 2; j++) { const MPoly *f_hit = f_hit_pair[j]; - int l = f_hit->loopstart; - for (int k = 0; k < f_hit->totloop; k++, l++) { - r_intersect[l] = 1.0f; + int l_index = f_hit->loopstart; + for (int k = 0; k < f_hit->totloop; k++, l_index++) { + r_intersect[l_index] = 1.0f; } } } @@ -3674,9 +4149,9 @@ static void statvis_calc_distort(const MeshRenderData *mr, float *r_distort) BM_mesh_elem_index_ensure(em->bm, BM_VERT); } - int l = 0; - int p = 0; - BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, p) { + int l_index = 0; + int f_index = 0; + BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, f_index) { float fac = -1.0f; if (f->len > 3) { @@ -3688,7 +4163,7 @@ static void statvis_calc_distort(const MeshRenderData *mr, float *r_distort) const float *no_face; float no_corner[3]; if (mr->bm_vert_coords != NULL) { - no_face = mr->bm_poly_normals[p]; + no_face = mr->bm_poly_normals[f_index]; BM_loop_calc_face_normal_safe_vcos(l_iter, no_face, mr->bm_vert_coords, no_corner); } else { @@ -3707,24 +4182,24 @@ static void statvis_calc_distort(const MeshRenderData *mr, float *r_distort) } fac = distort_remap(fac, min, max, minmax_irange); - for (int i = 0; i < f->len; i++, l++) { - r_distort[l] = fac; + for (int i = 0; i < f->len; i++, l_index++) { + r_distort[l_index] = fac; } } } else { - const MPoly *mpoly = mr->mpoly; - for (int p = 0, l = 0; p < mr->poly_len; p++, mpoly++) { + const MPoly *mp = mr->mpoly; + for (int mp_index = 0, l_index = 0; mp_index < mr->poly_len; mp_index++, mp++) { float fac = -1.0f; - if (mpoly->totloop > 3) { - float *f_no = mr->poly_normals[p]; + if (mp->totloop > 3) { + float *f_no = mr->poly_normals[mp_index]; fac = 0.0f; - for (int i = 1; i <= mpoly->totloop; i++) { - const MLoop *l_prev = &mr->mloop[mpoly->loopstart + (i - 1) % mpoly->totloop]; - const MLoop *l_curr = &mr->mloop[mpoly->loopstart + (i + 0) % mpoly->totloop]; - const MLoop *l_next = &mr->mloop[mpoly->loopstart + (i + 1) % mpoly->totloop]; + for (int i = 1; i <= mp->totloop; i++) { + const MLoop *l_prev = &mr->mloop[mp->loopstart + (i - 1) % mp->totloop]; + const MLoop *l_curr = &mr->mloop[mp->loopstart + (i + 0) % mp->totloop]; + const MLoop *l_next = &mr->mloop[mp->loopstart + (i + 1) % mp->totloop]; float no_corner[3]; normal_tri_v3(no_corner, mr->mvert[l_prev->v].co, @@ -3740,8 +4215,8 @@ static void statvis_calc_distort(const MeshRenderData *mr, float *r_distort) } fac = distort_remap(fac, min, max, minmax_irange); - for (int i = 0; i < mpoly->totloop; i++, l++) { - r_distort[l] = fac; + for (int i = 0; i < mp->totloop; i++, l_index++) { + r_distort[l_index] = fac; } } } @@ -3791,34 +4266,34 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp) BMLoop *l_iter, *l_first; l_iter = l_first = BM_FACE_FIRST_LOOP(efa); do { - int l = BM_elem_index_get(l_iter); - int v = BM_elem_index_get(l_iter->v); - r_sharp[l] = sharp_remap(vert_angles[v], min, max, minmax_irange); + int l_index = BM_elem_index_get(l_iter); + int v_index = BM_elem_index_get(l_iter->v); + r_sharp[l_index] = sharp_remap(vert_angles[v_index], min, max, minmax_irange); } while ((l_iter = l_iter->next) != l_first); } } else { /* first assign float values to verts */ - const MPoly *mpoly = mr->mpoly; + const MPoly *mp = mr->mpoly; EdgeHash *eh = BLI_edgehash_new_ex(__func__, mr->edge_len); - for (int p = 0; p < mr->poly_len; p++, mpoly++) { - for (int i = 0; i < mpoly->totloop; i++) { - const MLoop *l_curr = &mr->mloop[mpoly->loopstart + (i + 0) % mpoly->totloop]; - const MLoop *l_next = &mr->mloop[mpoly->loopstart + (i + 1) % mpoly->totloop]; + for (int mp_index = 0; mp_index < mr->poly_len; mp_index++, mp++) { + for (int i = 0; i < mp->totloop; i++) { + const MLoop *l_curr = &mr->mloop[mp->loopstart + (i + 0) % mp->totloop]; + const MLoop *l_next = &mr->mloop[mp->loopstart + (i + 1) % mp->totloop]; const MVert *v_curr = &mr->mvert[l_curr->v]; const MVert *v_next = &mr->mvert[l_next->v]; float angle; void **pval; bool value_is_init = BLI_edgehash_ensure_p(eh, l_curr->v, l_next->v, &pval); if (!value_is_init) { - *pval = mr->poly_normals[p]; + *pval = mr->poly_normals[mp_index]; /* non-manifold edge, yet... */ continue; } else if (*pval != NULL) { - const float *f1_no = mr->poly_normals[p]; + const float *f1_no = mr->poly_normals[mp_index]; const float *f2_no = *pval; angle = angle_normalized_v3v3(f1_no, f2_no); angle = is_edge_convex_v3(v_curr->co, v_next->co, f1_no, f2_no) ? angle : -angle; @@ -3851,9 +4326,9 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp) BLI_edgehashIterator_free(ehi); BLI_edgehash_free(eh, NULL); - const MLoop *mloop = mr->mloop; - for (int l = 0; l < mr->loop_len; l++, mloop++) { - r_sharp[l] = sharp_remap(vert_angles[mloop->v], min, max, minmax_irange); + const MLoop *ml = mr->mloop; + for (int l_index = 0; l_index < mr->loop_len; l_index++, ml++) { + r_sharp[l_index] = sharp_remap(vert_angles[ml->v], min, max, minmax_irange); } } @@ -3917,40 +4392,44 @@ static void *extract_fdots_pos_init(const MeshRenderData *mr, void *buf) return vbo->data; } -static void extract_fdots_pos_loop_bmesh(const MeshRenderData *mr, - int UNUSED(l), - BMLoop *loop, - void *data) +static void extract_fdots_pos_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *data) { - float(*center)[3] = (float(*)[3])data; - float w = 1.0f / (float)loop->f->len; - madd_v3_v3fl(center[BM_elem_index_get(loop->f)], bm_vert_co_get(mr, loop->v), w); + float(*center)[3] = data; + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + float w = 1.0f / (float)l->f->len; + madd_v3_v3fl(center[BM_elem_index_get(l->f)], bm_vert_co_get(mr, l->v), w); + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); } -static void extract_fdots_pos_loop_mesh(const MeshRenderData *mr, - int UNUSED(l), - const MLoop *mloop, - int p, - const MPoly *mpoly, - void *data) +static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *data) { float(*center)[3] = (float(*)[3])data; - const MVert *mvert = &mr->mvert[mloop->v]; - if (mr->use_subsurf_fdots) { - if (mvert->flag & ME_VERT_FACEDOT) { - copy_v3_v3(center[p], mvert->co); + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + const MVert *mv = &mr->mvert[ml->v]; + if (mr->use_subsurf_fdots) { + if (mv->flag & ME_VERT_FACEDOT) { + copy_v3_v3(center[mp_index], mv->co); + } + } + else { + float w = 1.0f / (float)mp->totloop; + madd_v3_v3fl(center[mp_index], mv->co, w); } } - else { - float w = 1.0f / (float)mpoly->totloop; - madd_v3_v3fl(center[p], mvert->co, w); - } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } static const MeshExtract extract_fdots_pos = { .init = extract_fdots_pos_init, - .iter_loop_bm = extract_fdots_pos_loop_bmesh, - .iter_loop_mesh = extract_fdots_pos_loop_mesh, + .iter_poly_bm = extract_fdots_pos_iter_poly_bm, + .iter_poly_mesh = extract_fdots_pos_iter_poly_mesh, .data_flag = 0, .use_threading = true, }; @@ -4072,30 +4551,42 @@ static void *extract_fdots_uv_init(const MeshRenderData *mr, void *buf) return data; } -static void extract_fdots_uv_loop_bmesh(const MeshRenderData *UNUSED(mr), - int UNUSED(l), - BMLoop *loop, - void *_data) +static void extract_fdots_uv_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *_data) { - MeshExtract_FdotUV_Data *data = (MeshExtract_FdotUV_Data *)_data; - float w = 1.0f / (float)loop->f->len; - const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, data->cd_ofs); - madd_v2_v2fl(data->vbo_data[BM_elem_index_get(loop->f)], luv->uv, w); + MeshExtract_FdotUV_Data *data = _data; + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + float w = 1.0f / (float)l->f->len; + const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, data->cd_ofs); + madd_v2_v2fl(data->vbo_data[BM_elem_index_get(l->f)], luv->uv, w); + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); } -static void extract_fdots_uv_loop_mesh( - const MeshRenderData *mr, int l, const MLoop *mloop, int p, const MPoly *mpoly, void *_data) +static void extract_fdots_uv_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *_data) { - MeshExtract_FdotUV_Data *data = (MeshExtract_FdotUV_Data *)_data; + MeshExtract_FdotUV_Data *data = _data; if (mr->use_subsurf_fdots) { - const MVert *mvert = &mr->mvert[mloop->v]; - if (mvert->flag & ME_VERT_FACEDOT) { - copy_v2_v2(data->vbo_data[p], data->uv_data[l].uv); + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + const MVert *mv = &mr->mvert[ml->v]; + if (mv->flag & ME_VERT_FACEDOT) { + copy_v2_v2(data->vbo_data[mp_index], data->uv_data[ml_index].uv); + } } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } else { - float w = 1.0f / (float)mpoly->totloop; - madd_v2_v2fl(data->vbo_data[p], data->uv_data[l].uv, w); + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + float w = 1.0f / (float)mp->totloop; + madd_v2_v2fl(data->vbo_data[mp_index], data->uv_data[ml_index].uv, w); + } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } } @@ -4108,8 +4599,8 @@ static void extract_fdots_uv_finish(const MeshRenderData *UNUSED(mr), static const MeshExtract extract_fdots_uv = { .init = extract_fdots_uv_init, - .iter_loop_bm = extract_fdots_uv_loop_bmesh, - .iter_loop_mesh = extract_fdots_uv_loop_mesh, + .iter_poly_bm = extract_fdots_uv_iter_poly_bm, + .iter_poly_mesh = extract_fdots_uv_iter_poly_mesh, .finish = extract_fdots_uv_finish, .data_flag = 0, .use_threading = true, @@ -4141,31 +4632,35 @@ static void *extract_fdots_edituv_data_init(const MeshRenderData *mr, void *buf) return data; } -static void extract_fdots_edituv_data_loop_bmesh(const MeshRenderData *mr, - int UNUSED(l), - BMLoop *loop, - void *_data) +static void extract_fdots_edituv_data_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *_data) { - MeshExtract_EditUVFdotData_Data *data = (MeshExtract_EditUVFdotData_Data *)_data; - EditLoopData *eldata = data->vbo_data + BM_elem_index_get(loop->f); - memset(eldata, 0x0, sizeof(*eldata)); - mesh_render_data_face_flag(mr, loop->f, data->cd_ofs, eldata); + MeshExtract_EditUVFdotData_Data *data = _data; + EXTRACT_POLY_FOREACH_BM_BEGIN(f, f_index, params, mr) + { + EditLoopData *eldata = &data->vbo_data[BM_elem_index_get(f)]; + memset(eldata, 0x0, sizeof(*eldata)); + mesh_render_data_face_flag(mr, f, data->cd_ofs, eldata); + } + EXTRACT_POLY_FOREACH_BM_END; } -static void extract_fdots_edituv_data_loop_mesh(const MeshRenderData *mr, - int UNUSED(l), - const MLoop *UNUSED(mloop), - int p, - const MPoly *UNUSED(mpoly), - void *_data) +static void extract_fdots_edituv_data_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *_data) { - MeshExtract_EditUVFdotData_Data *data = (MeshExtract_EditUVFdotData_Data *)_data; - EditLoopData *eldata = data->vbo_data + p; - memset(eldata, 0x0, sizeof(*eldata)); - BMFace *efa = bm_original_face_get(mr, p); - if (efa) { - mesh_render_data_face_flag(mr, efa, data->cd_ofs, eldata); + MeshExtract_EditUVFdotData_Data *data = _data; + EXTRACT_POLY_FOREACH_MESH_BEGIN(mp, mp_index, params, mr) + { + EditLoopData *eldata = &data->vbo_data[mp_index]; + memset(eldata, 0x0, sizeof(*eldata)); + BMFace *efa = bm_original_face_get(mr, mp_index); + if (efa) { + mesh_render_data_face_flag(mr, efa, data->cd_ofs, eldata); + } } + EXTRACT_POLY_FOREACH_MESH_END; } static void extract_fdots_edituv_data_finish(const MeshRenderData *UNUSED(mr), @@ -4177,8 +4672,8 @@ static void extract_fdots_edituv_data_finish(const MeshRenderData *UNUSED(mr), static const MeshExtract extract_fdots_edituv_data = { .init = extract_fdots_edituv_data_init, - .iter_loop_bm = extract_fdots_edituv_data_loop_bmesh, - .iter_loop_mesh = extract_fdots_edituv_data_loop_mesh, + .iter_poly_bm = extract_fdots_edituv_data_iter_poly_bm, + .iter_poly_mesh = extract_fdots_edituv_data_iter_poly_mesh, .finish = extract_fdots_edituv_data_finish, .data_flag = 0, .use_threading = true, @@ -4261,135 +4756,176 @@ static void *extract_select_idx_init(const MeshRenderData *mr, void *buf) * index VBO's. We could upload the p/e/v_origindex as a buffer texture and sample it inside the * shader to output original index. */ -static void extract_poly_idx_loop_bmesh(const MeshRenderData *UNUSED(mr), - int l, - BMLoop *loop, - void *data) +static void extract_poly_idx_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *data) { - ((uint32_t *)data)[l] = BM_elem_index_get(loop->f); + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + ((uint32_t *)data)[l_index] = BM_elem_index_get(l->f); + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); } -static void extract_edge_idx_loop_bmesh(const MeshRenderData *UNUSED(mr), - int l, - BMLoop *loop, - void *data) +static void extract_edge_idx_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *data) { - ((uint32_t *)data)[l] = BM_elem_index_get(loop->e); + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + ((uint32_t *)data)[l_index] = BM_elem_index_get(l->e); + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); } -static void extract_vert_idx_loop_bmesh(const MeshRenderData *UNUSED(mr), - int l, - BMLoop *loop, - void *data) +static void extract_vert_idx_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *data) { - ((uint32_t *)data)[l] = BM_elem_index_get(loop->v); + EXTRACT_POLY_AND_LOOP_FOREACH_BM_BEGIN(l, l_index, params, mr) + { + ((uint32_t *)data)[l_index] = BM_elem_index_get(l->v); + } + EXTRACT_POLY_AND_LOOP_FOREACH_BM_END(l); } -static void extract_edge_idx_ledge_bmesh(const MeshRenderData *mr, int e, BMEdge *eed, void *data) +static void extract_edge_idx_iter_ledge_bm(const MeshRenderData *mr, + const ExtractLEdgeBMesh_Params *params, + void *data) { - ((uint32_t *)data)[mr->loop_len + e * 2 + 0] = BM_elem_index_get(eed); - ((uint32_t *)data)[mr->loop_len + e * 2 + 1] = BM_elem_index_get(eed); + EXTRACT_LEDGE_FOREACH_BM_BEGIN(eed, ledge_index, params) + { + ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 0] = BM_elem_index_get(eed); + ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 1] = BM_elem_index_get(eed); + } + EXTRACT_LEDGE_FOREACH_BM_END; } -static void extract_vert_idx_ledge_bmesh(const MeshRenderData *mr, int e, BMEdge *eed, void *data) +static void extract_vert_idx_iter_ledge_bm(const MeshRenderData *mr, + const ExtractLEdgeBMesh_Params *params, + void *data) { - ((uint32_t *)data)[mr->loop_len + e * 2 + 0] = BM_elem_index_get(eed->v1); - ((uint32_t *)data)[mr->loop_len + e * 2 + 1] = BM_elem_index_get(eed->v2); + EXTRACT_LEDGE_FOREACH_BM_BEGIN(eed, ledge_index, params) + { + ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 0] = BM_elem_index_get(eed->v1); + ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 1] = BM_elem_index_get(eed->v2); + } + EXTRACT_LEDGE_FOREACH_BM_END; } -static void extract_vert_idx_lvert_bmesh(const MeshRenderData *mr, int v, BMVert *eve, void *data) +static void extract_vert_idx_iter_lvert_bm(const MeshRenderData *mr, + const ExtractLVertBMesh_Params *params, + void *data) { - ((uint32_t *)data)[mr->loop_len + mr->edge_loose_len * 2 + v] = BM_elem_index_get(eve); + const int offset = mr->loop_len + (mr->edge_loose_len * 2); + EXTRACT_LVERT_FOREACH_BM_BEGIN(eve, lvert_index, params) + { + ((uint32_t *)data)[offset + lvert_index] = BM_elem_index_get(eve); + } + EXTRACT_LVERT_FOREACH_BM_END; } -static void extract_poly_idx_loop_mesh(const MeshRenderData *mr, - int l, - const MLoop *UNUSED(mloop), - int p, - const MPoly *UNUSED(mpoly), - void *data) +static void extract_poly_idx_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *data) { - ((uint32_t *)data)[l] = (mr->p_origindex) ? mr->p_origindex[p] : p; + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + ((uint32_t *)data)[ml_index] = (mr->p_origindex) ? mr->p_origindex[mp_index] : mp_index; + } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } -static void extract_edge_idx_loop_mesh(const MeshRenderData *mr, - int l, - const MLoop *mloop, - int UNUSED(p), - const MPoly *UNUSED(mpoly), - void *data) +static void extract_edge_idx_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *data) { - ((uint32_t *)data)[l] = (mr->e_origindex) ? mr->e_origindex[mloop->e] : mloop->e; + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + ((uint32_t *)data)[ml_index] = (mr->e_origindex) ? mr->e_origindex[ml->e] : ml->e; + } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } -static void extract_vert_idx_loop_mesh(const MeshRenderData *mr, - int l, - const MLoop *mloop, - int UNUSED(p), - const MPoly *UNUSED(mpoly), - void *data) +static void extract_vert_idx_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *data) { - ((uint32_t *)data)[l] = (mr->v_origindex) ? mr->v_origindex[mloop->v] : mloop->v; + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_BEGIN(mp, mp_index, ml, ml_index, params, mr) + { + ((uint32_t *)data)[ml_index] = (mr->v_origindex) ? mr->v_origindex[ml->v] : ml->v; + } + EXTRACT_POLY_AND_LOOP_FOREACH_MESH_END; } -static void extract_edge_idx_ledge_mesh(const MeshRenderData *mr, - int e, - const MEdge *UNUSED(medge), - void *data) +static void extract_edge_idx_iter_ledge_mesh(const MeshRenderData *mr, + const ExtractLEdgeMesh_Params *params, + void *data) { - int e_idx = mr->ledges[e]; - int e_orig = (mr->e_origindex) ? mr->e_origindex[e_idx] : e_idx; - ((uint32_t *)data)[mr->loop_len + e * 2 + 0] = e_orig; - ((uint32_t *)data)[mr->loop_len + e * 2 + 1] = e_orig; + EXTRACT_LEDGE_FOREACH_MESH_BEGIN(med, ledge_index, params, mr) + { + const int e_index = mr->ledges[ledge_index]; + const int e_orig = (mr->e_origindex) ? mr->e_origindex[e_index] : e_index; + ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 0] = e_orig; + ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 1] = e_orig; + } + EXTRACT_LEDGE_FOREACH_MESH_END; } -static void extract_vert_idx_ledge_mesh(const MeshRenderData *mr, - int e, - const MEdge *medge, - void *data) +static void extract_vert_idx_iter_ledge_mesh(const MeshRenderData *mr, + const ExtractLEdgeMesh_Params *params, + void *data) { - int v1_orig = (mr->v_origindex) ? mr->v_origindex[medge->v1] : medge->v1; - int v2_orig = (mr->v_origindex) ? mr->v_origindex[medge->v2] : medge->v2; - ((uint32_t *)data)[mr->loop_len + e * 2 + 0] = v1_orig; - ((uint32_t *)data)[mr->loop_len + e * 2 + 1] = v2_orig; + EXTRACT_LEDGE_FOREACH_MESH_BEGIN(med, ledge_index, params, mr) + { + int v1_orig = (mr->v_origindex) ? mr->v_origindex[med->v1] : med->v1; + int v2_orig = (mr->v_origindex) ? mr->v_origindex[med->v2] : med->v2; + ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 0] = v1_orig; + ((uint32_t *)data)[mr->loop_len + ledge_index * 2 + 1] = v2_orig; + } + EXTRACT_LEDGE_FOREACH_MESH_END; } -static void extract_vert_idx_lvert_mesh(const MeshRenderData *mr, - int v, - const MVert *UNUSED(mvert), - void *data) +static void extract_vert_idx_iter_lvert_mesh(const MeshRenderData *mr, + const ExtractLVertMesh_Params *params, + void *data) { - int v_idx = mr->lverts[v]; - int v_orig = (mr->v_origindex) ? mr->v_origindex[v_idx] : v_idx; - ((uint32_t *)data)[mr->loop_len + mr->edge_loose_len * 2 + v] = v_orig; + const int offset = mr->loop_len + (mr->edge_loose_len * 2); + EXTRACT_LVERT_FOREACH_MESH_BEGIN(med, lvert_index, params, mr) + { + const int v_index = mr->lverts[lvert_index]; + const int v_orig = (mr->v_origindex) ? mr->v_origindex[v_index] : v_index; + ((uint32_t *)data)[offset + lvert_index] = v_orig; + } + EXTRACT_LVERT_FOREACH_MESH_END; } static const MeshExtract extract_poly_idx = { .init = extract_select_idx_init, - .iter_loop_bm = extract_poly_idx_loop_bmesh, - .iter_loop_mesh = extract_poly_idx_loop_mesh, + .iter_poly_bm = extract_poly_idx_iter_poly_bm, + .iter_poly_mesh = extract_poly_idx_iter_poly_mesh, .data_flag = 0, .use_threading = true, }; static const MeshExtract extract_edge_idx = { .init = extract_select_idx_init, - .iter_loop_bm = extract_edge_idx_loop_bmesh, - .iter_loop_mesh = extract_edge_idx_loop_mesh, - .iter_ledge_bm = extract_edge_idx_ledge_bmesh, - .iter_ledge_mesh = extract_edge_idx_ledge_mesh, + .iter_poly_bm = extract_edge_idx_iter_poly_bm, + .iter_poly_mesh = extract_edge_idx_iter_poly_mesh, + .iter_ledge_bm = extract_edge_idx_iter_ledge_bm, + .iter_ledge_mesh = extract_edge_idx_iter_ledge_mesh, .data_flag = 0, .use_threading = true, }; static const MeshExtract extract_vert_idx = { .init = extract_select_idx_init, - .iter_loop_bm = extract_vert_idx_loop_bmesh, - .iter_loop_mesh = extract_vert_idx_loop_mesh, - .iter_ledge_bm = extract_vert_idx_ledge_bmesh, - .iter_ledge_mesh = extract_vert_idx_ledge_mesh, - .iter_lvert_bm = extract_vert_idx_lvert_bmesh, - .iter_lvert_mesh = extract_vert_idx_lvert_mesh, + .iter_poly_bm = extract_vert_idx_iter_poly_bm, + .iter_poly_mesh = extract_vert_idx_iter_poly_mesh, + .iter_ledge_bm = extract_vert_idx_iter_ledge_bm, + .iter_ledge_mesh = extract_vert_idx_iter_ledge_mesh, + .iter_lvert_bm = extract_vert_idx_iter_lvert_bm, + .iter_lvert_mesh = extract_vert_idx_iter_lvert_mesh, .data_flag = 0, .use_threading = true, }; @@ -4407,28 +4943,41 @@ static void *extract_select_fdot_idx_init(const MeshRenderData *mr, void *buf) return vbo->data; } -static void extract_fdot_idx_loop_bmesh(const MeshRenderData *UNUSED(mr), - int UNUSED(l), - BMLoop *loop, - void *data) +static void extract_fdot_idx_iter_poly_bm(const MeshRenderData *mr, + const ExtractPolyBMesh_Params *params, + void *data) { - ((uint32_t *)data)[BM_elem_index_get(loop->f)] = BM_elem_index_get(loop->f); + EXTRACT_POLY_FOREACH_BM_BEGIN(f, f_index, params, mr) + { + ((uint32_t *)data)[f_index] = f_index; + } + EXTRACT_POLY_FOREACH_BM_END; } -static void extract_fdot_idx_loop_mesh(const MeshRenderData *mr, - int UNUSED(l), - const MLoop *UNUSED(mloop), - int p, - const MPoly *UNUSED(mpoly), - void *data) +static void extract_fdot_idx_iter_poly_mesh(const MeshRenderData *mr, + const ExtractPolyMesh_Params *params, + void *data) { - ((uint32_t *)data)[p] = (mr->p_origindex) ? mr->p_origindex[p] : p; + if (mr->p_origindex != NULL) { + EXTRACT_POLY_FOREACH_MESH_BEGIN(mp, mp_index, params, mr) + { + ((uint32_t *)data)[mp_index] = mr->p_origindex[mp_index]; + } + EXTRACT_POLY_FOREACH_MESH_END; + } + else { + EXTRACT_POLY_FOREACH_MESH_BEGIN(mp, mp_index, params, mr) + { + ((uint32_t *)data)[mp_index] = mp_index; + } + EXTRACT_POLY_FOREACH_MESH_END; + } } static const MeshExtract extract_fdot_idx = { .init = extract_select_fdot_idx_init, - .iter_loop_bm = extract_fdot_idx_loop_bmesh, - .iter_loop_mesh = extract_fdot_idx_loop_mesh, + .iter_poly_bm = extract_fdot_idx_iter_poly_bm, + .iter_poly_mesh = extract_fdot_idx_iter_poly_mesh, .data_flag = 0, .use_threading = true, }; @@ -4512,67 +5061,69 @@ BLI_INLINE void mesh_extract_iter(const MeshRenderData *mr, switch (mr->extract_type) { case MR_EXTRACT_BMESH: if (iter_type & MR_ITER_LOOPTRI) { - int t_end = min_ii(mr->tri_len, end); - for (int t = start; t < t_end; t++) { - BMLoop **elt = &mr->edit_bmesh->looptris[t][0]; - extract->iter_looptri_bm(mr, t, elt, user_data); - } + extract->iter_looptri_bm(mr, + &(const ExtractTriBMesh_Params){ + .looptris = mr->edit_bmesh->looptris, + .tri_range = {start, min_ii(mr->tri_len, end)}, + }, + user_data); } - if (iter_type & MR_ITER_LOOP) { - int l_end = min_ii(mr->poly_len, end); - for (int f = start; f < l_end; f++) { - BMFace *efa = BM_face_at_index(mr->bm, f); - BMLoop *l_iter, *l_first; - l_iter = l_first = BM_FACE_FIRST_LOOP(efa); - do { - extract->iter_loop_bm(mr, BM_elem_index_get(l_iter), l_iter, user_data); - } while ((l_iter = l_iter->next) != l_first); - } + if (iter_type & MR_ITER_POLY) { + extract->iter_poly_bm(mr, + &(const ExtractPolyBMesh_Params){ + .poly_range = {start, min_ii(mr->poly_len, end)}, + }, + user_data); } if (iter_type & MR_ITER_LEDGE) { - int le_end = min_ii(mr->edge_loose_len, end); - for (int e = start; e < le_end; e++) { - BMEdge *eed = BM_edge_at_index(mr->bm, mr->ledges[e]); - extract->iter_ledge_bm(mr, e, eed, user_data); - } + extract->iter_ledge_bm(mr, + &(const ExtractLEdgeBMesh_Params){ + .ledge = mr->ledges, + .ledge_range = {start, min_ii(mr->edge_loose_len, end)}, + }, + user_data); } if (iter_type & MR_ITER_LVERT) { - int lv_end = min_ii(mr->vert_loose_len, end); - for (int v = start; v < lv_end; v++) { - BMVert *eve = BM_vert_at_index(mr->bm, mr->lverts[v]); - extract->iter_lvert_bm(mr, v, eve, user_data); - } + extract->iter_lvert_bm(mr, + &(const ExtractLVertBMesh_Params){ + .lvert = mr->lverts, + .lvert_range = {start, min_ii(mr->vert_loose_len, end)}, + }, + user_data); } break; case MR_EXTRACT_MAPPED: case MR_EXTRACT_MESH: if (iter_type & MR_ITER_LOOPTRI) { - int t_end = min_ii(mr->tri_len, end); - for (int t = start; t < t_end; t++) { - extract->iter_looptri_mesh(mr, t, &mr->mlooptri[t], user_data); - } + extract->iter_looptri_mesh(mr, + &(const ExtractTriMesh_Params){ + .mlooptri = mr->mlooptri, + .tri_range = {start, min_ii(mr->tri_len, end)}, + }, + user_data); } - if (iter_type & MR_ITER_LOOP) { - int l_end = min_ii(mr->poly_len, end); - for (int p = start; p < l_end; p++) { - const MPoly *mpoly = &mr->mpoly[p]; - int l = mpoly->loopstart; - for (int i = 0; i < mpoly->totloop; i++, l++) { - extract->iter_loop_mesh(mr, l, &mr->mloop[l], p, mpoly, user_data); - } - } + if (iter_type & MR_ITER_POLY) { + extract->iter_poly_mesh(mr, + &(const ExtractPolyMesh_Params){ + .poly_range = {start, min_ii(mr->poly_len, end)}, + }, + user_data); } if (iter_type & MR_ITER_LEDGE) { - int le_end = min_ii(mr->edge_loose_len, end); - for (int e = start; e < le_end; e++) { - extract->iter_ledge_mesh(mr, e, &mr->medge[mr->ledges[e]], user_data); - } + extract->iter_ledge_mesh(mr, + &(const ExtractLEdgeMesh_Params){ + .ledge = mr->ledges, + .ledge_range = {start, min_ii(mr->edge_loose_len, end)}, + }, + user_data); } if (iter_type & MR_ITER_LVERT) { - int lv_end = min_ii(mr->vert_loose_len, end); - for (int v = start; v < lv_end; v++) { - extract->iter_lvert_mesh(mr, v, &mr->mvert[mr->lverts[v]], user_data); - } + extract->iter_lvert_mesh(mr, + &(const ExtractLVertMesh_Params){ + .lvert = mr->lverts, + .lvert_range = {start, min_ii(mr->vert_loose_len, end)}, + }, + user_data); } break; } @@ -4799,10 +5350,10 @@ static void extract_task_create(struct TaskGraph *task_graph, task_graph, task_node_user_data_init, taskdata, MR_ITER_LOOPTRI, i, chunk_size); } } - if (taskdata->iter_type & MR_ITER_LOOP) { + if (taskdata->iter_type & MR_ITER_POLY) { for (int i = 0; i < mr->poly_len; i += chunk_size) { extract_range_task_create( - task_graph, task_node_user_data_init, taskdata, MR_ITER_LOOP, i, chunk_size); + task_graph, task_node_user_data_init, taskdata, MR_ITER_POLY, i, chunk_size); } } if (taskdata->iter_type & MR_ITER_LEDGE) { -- cgit v1.2.3