Cleanup: Simplify iteration over mesh faces, use utility functions

Utility functions make accessing the next and previous corner of a face
more obvious, and range based for loops make iterating over corners
or vertices in a face simpler too.
This commit is contained in:
Hans Goudey
2023-07-25 10:24:46 -04:00
parent 6b872079fe
commit 0e87e25b37
6 changed files with 43 additions and 69 deletions

View File

@@ -855,15 +855,11 @@ static void loop_manifold_fan_around_vert_next(const Span<int> corner_verts,
{
/* We need the previous loop, but current one is our vertex's loop. */
*r_mlfan_vert_index = *r_mlfan_curr_index;
if (--(*r_mlfan_curr_index) < face_fan_next.start()) {
*r_mlfan_curr_index = face_fan_next.start() + face_fan_next.size() - 1;
}
*r_mlfan_curr_index = face_corner_prev(face_fan_next, *r_mlfan_curr_index);
}
else {
/* We need the next loop, which is also our vertex's loop. */
if (++(*r_mlfan_curr_index) >= face_fan_next.start() + face_fan_next.size()) {
*r_mlfan_curr_index = face_fan_next.start();
}
*r_mlfan_curr_index = face_corner_next(face_fan_next, *r_mlfan_curr_index);
*r_mlfan_vert_index = *r_mlfan_curr_index;
}
}

View File

@@ -6,6 +6,8 @@
* \ingroup draw
*/
#include "BKE_mesh.hh"
#include "extract_mesh.hh"
#include "draw_cache_impl.h"
@@ -94,8 +96,7 @@ static void extract_edituv_data_iter_face_mesh(const MeshRenderData *mr,
if (eed == nullptr) {
/* 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 = face.start() + face.size() - 1;
const int l_prev = (ml_index == face.start()) ? ml_index_last : (ml_index - 1);
const int l_prev = bke::mesh::face_corner_prev(face, ml_index);
eed = bm_original_edge_get(mr, mr->corner_edges[l_prev]);
}
if (eed) {

View File

@@ -348,13 +348,9 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C,
}
else {
if (ED_mesh_pick_face(C, vc.obact, mval, ED_MESH_PICK_DEFAULT_FACE_DIST, &index)) {
const blender::IndexRange face = faces[index];
int fidx = face.size() - 1;
do {
const MDeformVert *dvert = &dverts[corner_verts[face[fidx]]];
found |= weight_paint_sample_enum_itemf__helper(dvert, defbase_tot, groups);
} while (fidx--);
for (const int vert : corner_verts.slice(faces[index])) {
found |= weight_paint_sample_enum_itemf__helper(&dverts[vert], defbase_tot, groups);
}
}
}
@@ -474,30 +470,25 @@ static bool weight_paint_set(Object *ob, float paintweight)
&me->pdata, CD_PROP_BOOL, ".select_poly");
for (const int i : faces.index_range()) {
const blender::IndexRange face = faces[i];
uint fidx = face.size() - 1;
if ((paint_selmode == SCE_SELECT_FACE) && !(select_poly && select_poly[i])) {
continue;
}
do {
const int vidx = corner_verts[face[fidx]];
if (!dvert[vidx].flag) {
if ((paint_selmode == SCE_SELECT_VERTEX) && !(select_vert && select_vert[vidx])) {
for (const int vert : corner_verts.slice(faces[i])) {
if (!dvert[vert].flag) {
if ((paint_selmode == SCE_SELECT_VERTEX) && !(select_vert && select_vert[vert])) {
continue;
}
dw = BKE_defvert_ensure_index(&dvert[vidx], vgroup_active);
dw = BKE_defvert_ensure_index(&dvert[vert], vgroup_active);
if (dw) {
dw_prev = BKE_defvert_ensure_index(wpp.wpaint_prev + vidx, vgroup_active);
dw_prev = BKE_defvert_ensure_index(wpp.wpaint_prev + vert, vgroup_active);
dw_prev->weight = dw->weight; /* set the undo weight */
dw->weight = paintweight;
if (me->symmetry & ME_SYMMETRY_X) {
/* x mirror painting */
int j = mesh_get_x_mirror_vert(ob, nullptr, vidx, topology);
int j = mesh_get_x_mirror_vert(ob, nullptr, vert, topology);
if (j >= 0) {
/* copy, not paint again */
if (vgroup_mirror != -1) {
@@ -513,10 +504,9 @@ static bool weight_paint_set(Object *ob, float paintweight)
}
}
}
dvert[vidx].flag = 1;
dvert[vert].flag = 1;
}
} while (fidx--);
}
}
{

View File

@@ -106,20 +106,15 @@ void MOD_get_texture_coords(MappingInfoModifierData *dmd,
/* verts are given the UV from the first face that uses them */
for (const int i : faces.index_range()) {
const IndexRange face = faces[i];
uint fidx = face.size() - 1;
do {
uint lidx = face.start() + fidx;
const int vidx = corner_verts[lidx];
if (!BLI_BITMAP_TEST(done, vidx)) {
for (const int corner : face) {
const int vert = corner_verts[corner];
if (!BLI_BITMAP_TEST(done, vert)) {
/* remap UVs from [0, 1] to [-1, 1] */
r_texco[vidx][0] = (mloop_uv[lidx][0] * 2.0f) - 1.0f;
r_texco[vidx][1] = (mloop_uv[lidx][1] * 2.0f) - 1.0f;
BLI_BITMAP_ENABLE(done, vidx);
r_texco[vert][0] = (mloop_uv[corner][0] * 2.0f) - 1.0f;
r_texco[vert][1] = (mloop_uv[corner][1] * 2.0f) - 1.0f;
BLI_BITMAP_ENABLE(done, vert);
}
} while (fidx--);
}
}
MEM_freeN(done);

View File

@@ -207,22 +207,18 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
const blender::IndexRange face = faces[i];
if (projectors_num == 1) {
if (projectors[0].uci) {
uint fidx = face.size() - 1;
do {
uint lidx = face.start() + fidx;
const int vidx = corner_verts[lidx];
for (const int corner : face) {
const int vert = corner_verts[corner];
BLI_uvproject_from_camera(
mloop_uv[lidx], coords[vidx], static_cast<ProjCameraInfo *>(projectors[0].uci));
} while (fidx--);
mloop_uv[corner], coords[vert], static_cast<ProjCameraInfo *>(projectors[0].uci));
}
}
else {
/* apply transformed coords as UVs */
uint fidx = face.size() - 1;
do {
uint lidx = face.start() + fidx;
const int vidx = corner_verts[lidx];
copy_v2_v2(mloop_uv[lidx], coords[vidx]);
} while (fidx--);
for (const int corner : face) {
const int vert = corner_verts[corner];
copy_v2_v2(mloop_uv[corner], coords[vert]);
}
}
}
else {
@@ -250,21 +246,17 @@ static Mesh *uvprojectModifier_do(UVProjectModifierData *umd,
}
if (best_projector->uci) {
uint fidx = face.size() - 1;
do {
uint lidx = face.start() + fidx;
const int vidx = corner_verts[lidx];
for (const int corner : face) {
const int vert = corner_verts[corner];
BLI_uvproject_from_camera(
mloop_uv[lidx], coords[vidx], static_cast<ProjCameraInfo *>(best_projector->uci));
} while (fidx--);
mloop_uv[corner], coords[vert], static_cast<ProjCameraInfo *>(best_projector->uci));
}
}
else {
uint fidx = face.size() - 1;
do {
uint lidx = face.start() + fidx;
const int vidx = corner_verts[lidx];
mul_v2_project_m4_v3(mloop_uv[lidx], best_projector->projmat, coords[vidx]);
} while (fidx--);
for (const int corner : face) {
const int vert = corner_verts[corner];
mul_v2_project_m4_v3(mloop_uv[corner], best_projector->projmat, coords[vert]);
}
}
}
}

View File

@@ -1185,7 +1185,7 @@ static void extrude_individual_mesh_faces(
MutableSpan<int> face_verts = corner_verts.slice(face);
MutableSpan<int> face_edges = corner_edges.slice(face);
for (const int i : IndexRange(face.size())) {
for (const int i : face.index_range()) {
const int i_extrude = extrude_range[i];
new_vert_indices[i_extrude] = face_verts[i];
duplicate_edge_indices[i_extrude] = face_edges[i];
@@ -1194,7 +1194,7 @@ static void extrude_individual_mesh_faces(
face_edges[i] = duplicate_edge_range[i_extrude];
}
for (const int i : IndexRange(face.size())) {
for (const int i : face.index_range()) {
const int i_next = (i == face.size() - 1) ? 0 : i + 1;
const int i_extrude = extrude_range[i];
const int i_extrude_next = extrude_range[i_next];
@@ -1259,7 +1259,7 @@ static void extrude_individual_mesh_faces(
/* For the extruded edges, mix the data from the two neighboring original edges of
* the extruded face. */
for (const int i : IndexRange(face.size())) {
for (const int i : face.index_range()) {
const int i_prev = (i == 0) ? face.size() - 1 : i - 1;
const int i_extrude = extrude_range[i];
const int i_extrude_prev = extrude_range[i_prev];
@@ -1306,7 +1306,7 @@ static void extrude_individual_mesh_faces(
const Span<T> face_loop_data = data.slice(face);
const IndexRange extrude_range = group_per_face[i_selection];
for (const int i : IndexRange(face.size())) {
for (const int i : face.index_range()) {
const int i_next = (i == face.size() - 1) ? 0 : i + 1;
const int i_extrude = extrude_range[i];