Mesh: Replace MLoop struct with generic attributes #104424

Merged
Hans Goudey merged 261 commits from refactor-mesh-corners-generic into main 2023-03-20 15:55:25 +01:00
50 changed files with 639 additions and 615 deletions
Showing only changes of commit d0c2858714 - Show all commits

View File

@ -540,7 +540,7 @@ enum {
* Collection of #MLoopNorSpace basic storage & pre-allocation.
*/
typedef struct MLoopNorSpaceArray {
MLoopNorSpace **lspacearr; /* MLoop aligned array */
MLoopNorSpace **lspacearr; /* Face corner aligned array */
struct LinkNode
*loops_pool; /* Allocated once, avoids to call BLI_linklist_prepend_arena() for each loop! */
char data_type; /* Whether we store loop indices, or pointers to BMLoop. */
@ -756,12 +756,12 @@ void BKE_mesh_calc_volume(const float (*positions)[3],
int mverts_num,
const struct MLoopTri *mlooptri,
int looptri_num,
const struct MLoop *mloop,
const int *corner_verts,
float *r_volume,
float r_center[3]);
/**
* Flip a single MLoop's #MDisps structure,
* Flip a single corner's #MDisps structure,
* low level function to be called from face-flipping code which re-arranged the mdisps themselves.
*/
void BKE_mesh_mdisp_flip(struct MDisps *md, bool use_loop_mdisp_flip);

View File

@ -1938,7 +1938,7 @@ static void mesh_init_origspace(Mesh *mesh)
// const int numloop = mesh->totloop;
const Span<float3> positions = mesh->positions();
const Span<MPoly> polys = mesh->polys();
const Span<MLoop> loops = mesh->loops();
const Span<int> corner_verts = mesh->corner_verts();
const MPoly *mp = polys.data();
int i, j, k;
@ -1954,20 +1954,21 @@ static void mesh_init_origspace(Mesh *mesh)
}
}
else {
const MLoop *l = &loops[mp->loopstart];
float p_nor[3], co[3];
float mat[3][3];
float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
float translate[2], scale[2];
BKE_mesh_calc_poly_normal(
mp, l, reinterpret_cast<const float(*)[3]>(positions.data()), p_nor);
BKE_mesh_calc_poly_normal(mp,
&corner_verts[mp->loopstart],
reinterpret_cast<const float(*)[3]>(positions.data()),
p_nor);
axis_dominant_v3_to_m3(mat, p_nor);
vcos_2d.resize(mp->totloop);
for (j = 0; j < mp->totloop; j++, l++) {
mul_v3_m3v3(co, mat, positions[l->v]);
for (j = 0; j < mp->totloop; j++) {
mul_v3_m3v3(co, mat, positions[corner_verts[mp->totloop + j]]);
copy_v2_v2(vcos_2d[j], co);
for (k = 0; k < 2; k++) {

View File

@ -1404,7 +1404,7 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b
int numOfPolys = mesh->totpoly;
const MEdge *edges = BKE_mesh_edges(mesh);
const MPoly *polys = BKE_mesh_polys(mesh);
const MLoop *loops = BKE_mesh_loops(mesh);
const int *corner_verts = BKE_mesh_corner_verts(mesh);
/* count number of edges per vertex */
for (int i = 0; i < numOfEdges; i++) {
@ -1419,7 +1419,7 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b
* to locate points on "mesh edge" */
for (int i = 0; i < numOfPolys; i++) {
for (int j = 0; j < polys[i].totloop; j++) {
temp_data[loops[polys[i].loopstart + j].v]++;
temp_data[corner_verts[polys[i].loopstart + j]]++;
}
}
@ -1467,7 +1467,7 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, const b
typedef struct DynamicPaintSetInitColorData {
const DynamicPaintSurface *surface;
const MLoop *mloop;
const int *corner_verts;
const MLoopUV *mloopuv;
const MLoopTri *mlooptri;
const MLoopCol *mloopcol;
@ -1484,7 +1484,7 @@ static void dynamic_paint_set_init_color_tex_to_vcol_cb(
const PaintSurfaceData *sData = data->surface->data;
PaintPoint *pPoint = (PaintPoint *)sData->type_data;
const MLoop *mloop = data->mloop;
const int *corner_verts = data->corner_verts;
const MLoopTri *mlooptri = data->mlooptri;
const MLoopUV *mloopuv = data->mloopuv;
struct ImagePool *pool = data->pool;
@ -1496,7 +1496,7 @@ static void dynamic_paint_set_init_color_tex_to_vcol_cb(
for (int j = 3; j--;) {
TexResult texres = {0};
const uint vert = mloop[mlooptri[i].tri[j]].v;
const int vert = corner_verts[mlooptri[i].tri[j]];
/* remap to [-1.0, 1.0] */
uv[0] = mloopuv[mlooptri[i].tri[j]].uv[0] * 2.0f - 1.0f;
@ -1604,7 +1604,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
else if (surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) {
Tex *tex = surface->init_texture;
const MLoop *mloop = BKE_mesh_loops(mesh);
const int *corner_verts = BKE_mesh_corner_verts(mesh);
const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
const int tottri = BKE_mesh_runtime_looptri_len(mesh);
@ -1628,7 +1628,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
DynamicPaintSetInitColorData data = {
.surface = surface,
.mloop = mloop,
.corner_verts = corner_verts,
.mlooptri = mlooptri,
.mloopuv = mloopuv,
.pool = pool,
@ -1660,7 +1660,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
/* for vertex surface, just copy colors from mcol */
if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) {
const MLoop *mloop = BKE_mesh_loops(mesh);
const int *corner_verts = BKE_mesh_corner_verts(mesh);
const int totloop = mesh->totloop;
const MLoopCol *col = CustomData_get_layer_named(
&mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername);
@ -1669,7 +1669,7 @@ static void dynamicPaint_setInitialColor(const Scene *scene, DynamicPaintSurface
}
for (int i = 0; i < totloop; i++) {
rgba_uchar_to_float(pPoint[mloop[i].v].color, (const uchar *)&col[i].r);
rgba_uchar_to_float(pPoint[corner_verts[i]].color, (const uchar *)&col[i].r);
}
}
else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) {
@ -1776,7 +1776,7 @@ typedef struct DynamicPaintModifierApplyData {
float (*positions)[3];
const float (*vert_normals)[3];
const MLoop *mloop;
const int *corner_verts;
const MPoly *mpoly;
float (*fcolor)[4];
@ -1843,7 +1843,7 @@ static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata,
{
const DynamicPaintModifierApplyData *data = userdata;
const MLoop *mloop = data->mloop;
const int *corner_verts = data->corner_verts;
const MPoly *mpoly = data->mpoly;
const DynamicPaintSurface *surface = data->surface;
@ -1855,7 +1855,7 @@ static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata,
for (int j = 0; j < mpoly[p_index].totloop; j++) {
const int l_index = mpoly[p_index].loopstart + j;
const int v_index = mloop[l_index].v;
const int v_index = corner_verts[l_index];
/* save layer data to output layer */
/* apply color */
@ -1910,7 +1910,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
/* vertex color paint */
if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
const MLoop *mloop = BKE_mesh_loops(result);
const int *corner_verts = BKE_mesh_corner_verts(result);
const int totloop = result->totloop;
const MPoly *mpoly = BKE_mesh_polys(result);
const int totpoly = result->totpoly;
@ -1961,7 +1961,7 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object *
}
data.ob = ob;
data.mloop = mloop;
data.corner_verts = corner_verts;
data.mpoly = mpoly;
data.mloopcol = mloopcol;
data.mloopcol_wet = mloopcol_wet;
@ -2183,7 +2183,7 @@ typedef struct DynamicPaintCreateUVSurfaceData {
const MLoopTri *mlooptri;
const MLoopUV *mloopuv;
const MLoop *mloop;
const int *corner_verts;
const int tottri;
const Bounds2D *faceBB;
@ -2201,7 +2201,7 @@ static void dynamic_paint_create_uv_surface_direct_cb(
const MLoopTri *mlooptri = data->mlooptri;
const MLoopUV *mloopuv = data->mloopuv;
const MLoop *mloop = data->mloop;
const int *corner_verts = data->corner_verts;
const int tottri = data->tottri;
const Bounds2D *faceBB = data->faceBB;
@ -2273,9 +2273,9 @@ static void dynamic_paint_create_uv_surface_direct_cb(
tPoint->tri_index = i;
/* save vertex indexes */
tPoint->v1 = mloop[mlooptri[i].tri[0]].v;
tPoint->v2 = mloop[mlooptri[i].tri[1]].v;
tPoint->v3 = mloop[mlooptri[i].tri[2]].v;
tPoint->v1 = corner_verts[mlooptri[i].tri[0]];
tPoint->v2 = corner_verts[mlooptri[i].tri[1]];
tPoint->v3 = corner_verts[mlooptri[i].tri[2]];
sample = 5; /* make sure we exit sample loop as well */
break;
@ -2296,7 +2296,7 @@ static void dynamic_paint_create_uv_surface_neighbor_cb(
const MLoopTri *mlooptri = data->mlooptri;
const MLoopUV *mloopuv = data->mloopuv;
const MLoop *mloop = data->mloop;
const int *corner_verts = data->corner_verts;
uint32_t *active_points = data->active_points;
@ -2361,9 +2361,9 @@ static void dynamic_paint_create_uv_surface_neighbor_cb(
}
/* save vertex indexes */
tPoint->v1 = mloop[mlooptri[i].tri[0]].v;
tPoint->v2 = mloop[mlooptri[i].tri[1]].v;
tPoint->v3 = mloop[mlooptri[i].tri[2]].v;
tPoint->v1 = corner_verts[mlooptri[i].tri[0]];
tPoint->v2 = corner_verts[mlooptri[i].tri[1]];
tPoint->v3 = corner_verts[mlooptri[i].tri[2]];
break;
}
@ -2505,7 +2505,7 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa
int in_edge,
int depth)
{
const MLoop *mloop = data->mloop;
const int *corner_verts = data->corner_verts;
const MLoopTri *mlooptri = data->mlooptri;
const MLoopUV *mloopuv = data->mloopuv;
@ -2543,8 +2543,8 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa
}
/* Now find another face that is linked to that edge. */
const int vert0 = mloop[loop_idx[(edge_idx + 0)]].v;
const int vert1 = mloop[loop_idx[(edge_idx + 1) % 3]].v;
const int vert0 = corner_verts[loop_idx[(edge_idx + 0)]];
const int vert1 = corner_verts[loop_idx[(edge_idx + 1) % 3]];
/* Use a pre-computed vert-to-looptri mapping,
* speeds up things a lot compared to looping over all looptri. */
@ -2567,8 +2567,8 @@ static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceDa
/* Check edges for match, looping in the same order as the outer loop. */
for (int j = 0; j < 3; j++) {
const int overt0 = mloop[other_loop_idx[(j + 0)]].v;
const int overt1 = mloop[other_loop_idx[(j + 1) % 3]].v;
const int overt0 = corner_verts[other_loop_idx[(j + 0)]];
const int overt1 = corner_verts[other_loop_idx[(j + 1) % 3]];
/* Allow for swapped vertex order */
if (overt0 == vert0 && overt1 == vert1) {
@ -2803,7 +2803,6 @@ int dynamicPaint_createUVSurface(Scene *scene,
Vec3f *tempWeights = NULL;
const MLoopTri *mlooptri = NULL;
const MLoopUV *mloopuv = NULL;
const MLoop *mloop = NULL;
Bounds2D *faceBB = NULL;
int *final_index;
@ -2818,7 +2817,7 @@ int dynamicPaint_createUVSurface(Scene *scene,
return setError(canvas, N_("Cannot bake non-'image sequence' formats"));
}
mloop = BKE_mesh_loops(mesh);
const int *corner_verts = BKE_mesh_corner_verts(mesh);
mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
const int tottri = BKE_mesh_runtime_looptri_len(mesh);
@ -2902,7 +2901,7 @@ int dynamicPaint_createUVSurface(Scene *scene,
.tempWeights = tempWeights,
.mlooptri = mlooptri,
.mloopuv = mloopuv,
.mloop = mloop,
.corner_verts = corner_verts,
.tottri = tottri,
.faceBB = faceBB,
};
@ -2961,7 +2960,7 @@ int dynamicPaint_createUVSurface(Scene *scene,
mesh->totvert,
mlooptri,
tottri,
mloop,
corner_verts,
mesh->totloop);
int total_border = 0;
@ -3411,14 +3410,14 @@ static void mesh_tris_spherecast_dp(void *userdata,
const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
const float(*positions)[3] = data->positions;
const MLoopTri *mlooptri = data->looptri;
const MLoop *mloop = data->loop;
const int *corner_verts = data->corner_verts;
const float *t0, *t1, *t2;
float dist;
t0 = positions[mloop[mlooptri[index].tri[0]].v];
t1 = positions[mloop[mlooptri[index].tri[1]].v];
t2 = positions[mloop[mlooptri[index].tri[2]].v];
t0 = positions[corner_verts[mlooptri[index].tri[0]]];
t1 = positions[corner_verts[mlooptri[index].tri[1]]];
t2 = positions[corner_verts[mlooptri[index].tri[2]]];
dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2);
@ -3443,13 +3442,13 @@ static void mesh_tris_nearest_point_dp(void *userdata,
const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata;
const float(*positions)[3] = data->positions;
const MLoopTri *mlooptri = data->looptri;
const MLoop *mloop = data->loop;
const int *corner_verts = data->corner_verts;
float nearest_tmp[3], dist_sq;
const float *t0, *t1, *t2;
t0 = positions[mloop[mlooptri[index].tri[0]].v];
t1 = positions[mloop[mlooptri[index].tri[1]].v];
t2 = positions[mloop[mlooptri[index].tri[2]].v];
t0 = positions[corner_verts[mlooptri[index].tri[0]]];
t1 = positions[corner_verts[mlooptri[index].tri[1]]];
t2 = positions[corner_verts[mlooptri[index].tri[2]]];
closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2);
dist_sq = len_squared_v3v3(co, nearest_tmp);
@ -3882,7 +3881,7 @@ typedef struct DynamicPaintPaintData {
Mesh *mesh;
const float (*positions)[3];
const MLoop *mloop;
const int *corner_verts;
const MLoopTri *mlooptri;
const float brush_radius;
const float *avg_brushNor;
@ -3915,7 +3914,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(
const int c_index = data->c_index;
const float(*positions)[3] = data->positions;
const MLoop *mloop = data->mloop;
const int *corner_verts = data->corner_verts;
const MLoopTri *mlooptri = data->mlooptri;
const float brush_radius = data->brush_radius;
const float *avg_brushNor = data->avg_brushNor;
@ -3989,9 +3988,9 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(
/* For optimization sake, hit point normal isn't calculated in ray cast loop */
const int vtri[3] = {
mloop[mlooptri[hit.index].tri[0]].v,
mloop[mlooptri[hit.index].tri[1]].v,
mloop[mlooptri[hit.index].tri[2]].v,
corner_verts[mlooptri[hit.index].tri[0]],
corner_verts[mlooptri[hit.index].tri[1]],
corner_verts[mlooptri[hit.index].tri[2]],
};
float dot;
@ -4139,9 +4138,9 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(
float brushPointVelocity[3];
float velocity[3];
const int v1 = mloop[mlooptri[hitTri].tri[0]].v;
const int v2 = mloop[mlooptri[hitTri].tri[1]].v;
const int v3 = mloop[mlooptri[hitTri].tri[2]].v;
const int v1 = corner_verts[mlooptri[hitTri].tri[0]];
const int v2 = corner_verts[mlooptri[hitTri].tri[1]];
const int v3 = corner_verts[mlooptri[hitTri].tri[2]];
/* calculate barycentric weights for hit point */
interp_weights_tri_v3(weights, positions[v1], positions[v2], positions[v3], hitCoord);
@ -4241,7 +4240,6 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
Mesh *mesh = NULL;
Vec3f *brushVelocity = NULL;
const MLoopTri *mlooptri = NULL;
const MLoop *mloop = NULL;
if (brush->flags & MOD_DPAINT_USES_VELOCITY) {
dynamicPaint_brushMeshCalculateVelocity(
@ -4266,7 +4264,7 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
float(*positions)[3] = BKE_mesh_positions_for_write(mesh);
const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh);
mlooptri = BKE_mesh_runtime_looptri_ensure(mesh);
mloop = BKE_mesh_loops(mesh);
const int *corner_verts = BKE_mesh_corner_verts(mesh);
numOfVerts = mesh->totvert;
/* Transform collider vertices to global space
@ -4320,7 +4318,7 @@ static bool dynamicPaint_paintMesh(Depsgraph *depsgraph,
.c_index = c_index,
.mesh = mesh,
.positions = positions,
.mloop = mloop,
.corner_verts = corner_verts,
.mlooptri = mlooptri,
.brush_radius = brush_radius,
.avg_brushNor = avg_brushNor,

View File

@ -3384,7 +3384,7 @@ static Mesh *create_smoke_geometry(FluidDomainSettings *fds, Mesh *orgmesh, Obje
result = BKE_mesh_new_nomain(num_verts, 0, 0, num_faces * 4, num_faces);
float(*positions)[3] = BKE_mesh_positions_for_write(result);
mpolys = BKE_mesh_polys_for_write(result);
corner_verts = BKE_mesh_loops_for_write(result);
corner_verts = BKE_mesh_corner_verts_for_write(result);
if (num_verts) {
/* Volume bounds. */

View File

@ -262,6 +262,8 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
mesh->mvert = BKE_mesh_legacy_convert_positions_to_verts(
mesh, temp_arrays_for_legacy_format, vert_layers);
mesh->mloop = BKE_mesh_legacy_convert_corners_to_loops(
mesh, temp_arrays_for_legacy_format, loop_layers);
BKE_mesh_legacy_convert_hide_layers_to_flags(mesh);
BKE_mesh_legacy_convert_selection_layers_to_flags(mesh);
BKE_mesh_legacy_convert_material_indices_to_mpoly(mesh);
@ -273,7 +275,6 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
/* Set deprecated mesh data pointers for forward compatibility. */
mesh->medge = const_cast<MEdge *>(mesh->edges().data());
mesh->mpoly = const_cast<MPoly *>(mesh->polys().data());
mesh->mloop = const_cast<MLoop *>(mesh->loops().data());
mesh->dvert = const_cast<MDeformVert *>(mesh->deform_verts().data());
}

View File

@ -308,7 +308,8 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
Vector<Vert *> verts(me->totvert);
const Span<float3> mesh_positions = me->positions();
const Span<MPoly> polys = me->polys();
const Span<MLoop> loops = me->loops();
const Span<int> corner_verts = me->corner_verts();
const Span<int> corner_edges = me->corner_edges();
/* Allocate verts
* Skip the matrix multiplication for each point when there is no transform for a mesh,
@ -343,20 +344,19 @@ static IMesh meshes_to_imesh(Span<const Mesh *> meshes,
int flen = poly.totloop;
face_vert.resize(flen);
face_edge_orig.resize(flen);
const MLoop *l = &loops[poly.loopstart];
for (int i = 0; i < flen; ++i) {
int mverti = r_info->mesh_vert_offset[mi] + l->v;
const int corner_i = poly.loopstart + i;
int mverti = r_info->mesh_vert_offset[mi] + corner_verts[corner_i];
const Vert *fv = r_info->mesh_to_imesh_vert[mverti];
if (need_face_flip) {
face_vert[flen - i - 1] = fv;
int iedge = i < flen - 1 ? flen - i - 2 : flen - 1;
face_edge_orig[iedge] = e + l->e;
face_edge_orig[iedge] = e + corner_edges[corner_i];
}
else {
face_vert[i] = fv;
face_edge_orig[i] = e + l->e;
face_edge_orig[i] = e + corner_edges[corner_i];
}
++l;
}
r_info->mesh_to_imesh_face[f] = arena.add_face(face_vert, f, face_edge_orig);
++f;
@ -476,7 +476,7 @@ static int fill_orig_loops(const Face *f,
MutableSpan<int> r_orig_loops)
{
r_orig_loops.fill(-1);
const Span<MLoop> orig_loops = orig_me->loops();
const Span<int> orig_corner_verts = orig_me->corner_verts();
int orig_mplen = orig_mp->totloop;
if (f->size() != orig_mplen) {
@ -504,7 +504,7 @@ static int fill_orig_loops(const Face *f,
int offset = -1;
for (int i = 0; i < orig_mplen; ++i) {
int loop_i = i + orig_mp->loopstart;
if (orig_loops[loop_i].v == first_orig_v_in_orig_me) {
if (orig_corner_verts[loop_i] == first_orig_v_in_orig_me) {
offset = i;
break;
}
@ -515,7 +515,7 @@ static int fill_orig_loops(const Face *f,
int num_orig_loops_found = 0;
for (int mp_loop_index = 0; mp_loop_index < orig_mplen; ++mp_loop_index) {
int orig_mp_loop_index = (mp_loop_index + offset) % orig_mplen;
const MLoop *l = &orig_loops[orig_mp->loopstart + orig_mp_loop_index];
const int vert_i = orig_corner_verts[orig_mp->loopstart + orig_mp_loop_index];
int fv_orig = f->vert[mp_loop_index]->orig;
if (fv_orig != NO_INDEX) {
fv_orig -= orig_me_vert_offset;
@ -523,9 +523,9 @@ static int fill_orig_loops(const Face *f,
fv_orig = NO_INDEX;
}
}
if (l->v == fv_orig) {
const MLoop *lnext =
&orig_loops[orig_mp->loopstart + ((orig_mp_loop_index + 1) % orig_mplen)];
if (vert_i == fv_orig) {
const int vert_next =
orig_corner_verts[orig_mp->loopstart + ((orig_mp_loop_index + 1) % orig_mplen)];
int fvnext_orig = f->vert[(mp_loop_index + 1) % orig_mplen]->orig;
if (fvnext_orig != NO_INDEX) {
fvnext_orig -= orig_me_vert_offset;
@ -533,7 +533,7 @@ static int fill_orig_loops(const Face *f,
fvnext_orig = NO_INDEX;
}
}
if (lnext->v == fvnext_orig) {
if (vert_next == fvnext_orig) {
r_orig_loops[mp_loop_index] = orig_mp->loopstart + orig_mp_loop_index;
++num_orig_loops_found;
}
@ -553,18 +553,18 @@ static void get_poly2d_cos(const Mesh *me,
float r_axis_mat[3][3])
{
const Span<float3> positions = me->positions();
const Span<MLoop> loops = me->loops();
const Span<MLoop> poly_loops = loops.slice(mp->loopstart, mp->totloop);
const Span<int> corner_verts = me->corner_verts();
const Span<int> poly_verts = corner_verts.slice(mp->loopstart, mp->totloop);
/* Project coordinates to 2d in cos_2d, using normal as projection axis. */
float axis_dominant[3];
BKE_mesh_calc_poly_normal(mp,
&loops[mp->loopstart],
&corner_verts[mp->loopstart],
reinterpret_cast<const float(*)[3]>(positions.data()),
axis_dominant);
axis_dominant_v3_to_m3(r_axis_mat, axis_dominant);
for (const int i : poly_loops.index_range()) {
float3 co = positions[poly_loops[i].v];
for (const int i : poly_verts.index_range()) {
float3 co = positions[poly_verts[i]];
co = trans_mat * co;
mul_v2_m3v3(cos_2d[i], r_axis_mat, co);
}
@ -602,7 +602,7 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh,
}
CustomData *target_cd = &dest_mesh->ldata;
const Span<float3> dst_positions = dest_mesh->positions();
const Span<MLoop> dst_loops = dest_mesh->loops();
const Span<int> dst_corner_verts = dest_mesh->corner_verts();
for (int i = 0; i < mp->totloop; ++i) {
int loop_index = mp->loopstart + i;
int orig_loop_index = norig > 0 ? orig_loops[i] : -1;
@ -612,7 +612,7 @@ static void copy_or_interp_loop_attributes(Mesh *dest_mesh,
* The coordinate needs to be projected into 2d, just like the interpolating polygon's
* coordinates were. The `dest_mesh` coordinates are already in object 0 local space. */
float co[2];
mul_v2_m3v3(co, axis_mat, dst_positions[dst_loops[loop_index].v]);
mul_v2_m3v3(co, axis_mat, dst_positions[dst_corner_verts[loop_index]]);
interp_weights_poly_v2(weights.data(), cos_2d, orig_mp->totloop, co);
}
for (int source_layer_i = 0; source_layer_i < source_cd->totlayer; ++source_layer_i) {
@ -733,9 +733,8 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
result->attributes_for_write().lookup_or_add_for_write_only_span<int>("material_index",
ATTR_DOMAIN_FACE);
int cur_loop_index = 0;
MutableSpan<MLoop> dst_loops = result->loops_for_write();
MutableSpan<int> dst_corner_verts = result->corner_verts_for_write();
MutableSpan<MPoly> dst_polys = result->polys_for_write();
MLoop *l = dst_loops.data();
for (int fi : im->face_index_range()) {
const Face *f = im->face(fi);
const Mesh *orig_me;
@ -749,8 +748,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
for (int j : f->index_range()) {
const Vert *vf = f->vert[j];
const int vfi = im->lookup_vert(vf);
l->v = vfi;
++l;
dst_corner_verts[cur_loop_index] = vfi;
++cur_loop_index;
}
@ -776,6 +774,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
/* Now that the MEdges are populated, we can copy over the required attributes and custom layers.
*/
MutableSpan<MEdge> edges = result->edges_for_write();
const Span<int> dst_corner_edges = result->corner_edges();
for (int fi : im->face_index_range()) {
const Face *f = im->face(fi);
const MPoly *mp = &dst_polys[fi];
@ -785,7 +784,7 @@ static Mesh *imesh_to_mesh(IMesh *im, MeshesToIMeshInfo &mim)
int index_in_orig_me;
const MEdge *orig_medge = mim.input_medge_for_orig_index(
f->edge_orig[j], &orig_me, &index_in_orig_me);
int e_index = dst_loops[mp->loopstart + j].e;
int e_index = dst_corner_edges[mp->loopstart + j];
MEdge *medge = &edges[e_index];
copy_edge_attributes(result, medge, orig_medge, orig_me, e_index, index_in_orig_me);
}
@ -849,13 +848,13 @@ Mesh *direct_mesh_boolean(Span<const Mesh *> meshes,
/* Store intersecting edge indices. */
if (r_intersecting_edges != nullptr) {
const Span<MPoly> polys = result->polys();
const Span<MLoop> loops = result->loops();
const Span<int> corner_edges = result->corner_edges();
for (int fi : m_out.face_index_range()) {
const Face &face = *m_out.face(fi);
const MPoly &poly = polys[fi];
for (int corner_i : face.index_range()) {
if (face.is_intersect[corner_i]) {
int e_index = loops[poly.loopstart + corner_i].e;
int e_index = corner_edges[poly.loopstart + corner_i];
r_intersecting_edges->append(e_index);
}
}

View File

@ -206,7 +206,7 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh,
const int totpoly = mesh->totpoly;
const MEdge *src_edges = BKE_mesh_edges(mesh);
const MPoly *src_polys = BKE_mesh_polys(mesh);
const MLoop *src_loops = BKE_mesh_loops(mesh);
const MLoop *src_loops = BKE_mesh_corner_verts(mesh);
const int totvert_final = totvert - tot_vtargetmap;

View File

@ -116,7 +116,7 @@ void BKE_mesh_merge_customdata_for_apply_modifier(Mesh *me)
BKE_mesh_vert_loop_map_create(&vert_to_loop,
&vert_map_mem,
BKE_mesh_polys(me),
BKE_mesh_loops(me),
BKE_mesh_corner_verts(me),
me->totvert,
me->totpoly,
me->totloop);

View File

@ -317,7 +317,7 @@ Mesh *BKE_mesh_mirror_apply_mirror_on_axis_for_modifier(MirrorModifierData *mmd,
/* adjust mirrored poly loopstart indices, and reverse loop order (normals) */
mp = BKE_mesh_polys_for_write(result) + maxPolys;
int *corner_edges = BKE_mesh_loops_for_write(result);
int *corner_edges = BKE_mesh_corner_edges_for_write(result);
for (i = 0; i < maxPolys; i++, mp++) {
int j, e;

View File

@ -231,9 +231,9 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
(void)0
#define IS_REMOVED_EDGE(_me) (_me->v2 == _me->v1)
#define REMOVE_LOOP_TAG(_ml) \
#define REMOVE_LOOP_TAG(corner_i) \
{ \
_ml->e = INVALID_LOOP_EDGE_MARKER; \
corner_edges[corner_i] = INVALID_LOOP_EDGE_MARKER; \
free_flag.polyloops = do_fixes; \
} \
(void)0
@ -249,7 +249,6 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
blender::MutableVArraySpan<int> material_indices_span(material_indices.varray);
MEdge *me;
MLoop *ml;
MPoly *mp;
uint i, j;
int *v;
@ -604,27 +603,29 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
/* Ideally we would only have to do that once on all vertices
* before we start checking each poly, but several polys can use same vert,
* so we have to ensure here all verts of current poly are cleared. */
for (j = 0, ml = &mloops[sp->loopstart]; j < mp->totloop; j++, ml++) {
if (ml->v < totvert) {
BLI_BITMAP_DISABLE(vert_tag, ml->v);
for (j = 0; j < mp->totloop; j++) {
const int vert_i = corner_verts[sp->loopstart + j];
if (vert_i < totvert) {
BLI_BITMAP_DISABLE(vert_tag, vert_i);
}
}
/* Test all poly's loops' vert idx. */
for (j = 0, ml = &mloops[sp->loopstart]; j < mp->totloop; j++, ml++, v++) {
if (ml->v >= totvert) {
for (j = 0; j < mp->totloop; j++, v++) {
const int vert_i = corner_verts[sp->loopstart + j];
if (vert_i >= totvert) {
/* Invalid vert idx. */
PRINT_ERR("\tLoop %u has invalid vert reference (%u)", sp->loopstart + j, ml->v);
PRINT_ERR("\tLoop %u has invalid vert reference (%u)", sp->loopstart + j, vert_i);
sp->invalid = true;
}
else if (BLI_BITMAP_TEST(vert_tag, ml->v)) {
else if (BLI_BITMAP_TEST(vert_tag, vert_i)) {
PRINT_ERR("\tPoly %u has duplicated vert reference at corner (%u)", i, j);
sp->invalid = true;
}
else {
BLI_BITMAP_ENABLE(vert_tag, ml->v);
BLI_BITMAP_ENABLE(vert_tag, vert_i);
}
*v = ml->v;
*v = vert_i;
}
if (sp->invalid) {
@ -632,9 +633,12 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
/* Test all poly's loops. */
for (j = 0, ml = &mloops[sp->loopstart]; j < mp->totloop; j++, ml++) {
v1 = ml->v;
v2 = mloops[sp->loopstart + (j + 1) % mp->totloop].v;
for (j = 0; j < mp->totloop; j++) {
const int corner_i = sp->loopstart = j;
const int vert_i = corner_verts[corner_i];
const int edge_i = corner_edges[corner_i];
v1 = vert_i;
v2 = corner_verts[sp->loopstart + (j + 1) % mp->totloop];
if (!BLI_edgehash_haskey(edge_hash, v1, v2)) {
/* Edge not existing. */

*picky*: odd not to call this vert_i ? (used elsewhere).

\*picky\*: odd not to call this `vert_i` ? (used elsewhere).

I'm trying to use the vert name consistently actually (I just didn't want to change some existing variable names). The idea is that the index is all the vertex is really-- a marker in an array used to access various attributes. So it makes sense to use the simplest name for that. It's also shorter, easier to say and read, etc.

I'm trying to use the `vert` name consistently actually (I just didn't want to change some existing variable names). The idea is that the index is all the vertex is really-- a marker in an array used to access various attributes. So it makes sense to use the simplest name for that. It's also shorter, easier to say and read, etc.
PRINT_ERR("\tPoly %u needs missing edge (%d, %d)", sp->index, v1, v2);
@ -645,33 +649,33 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
sp->invalid = true;
}
}
else if (ml->e >= totedge) {
else if (edge_i >= totedge) {
/* Invalid edge idx.
* We already know from previous text that a valid edge exists, use it (if allowed)! */
if (do_fixes) {
int prev_e = ml->e;
ml->e = POINTER_AS_INT(BLI_edgehash_lookup(edge_hash, v1, v2));
int prev_e = edge_i;
corner_edges[corner_i] = POINTER_AS_INT(BLI_edgehash_lookup(edge_hash, v1, v2));
fix_flag.loops_edge = true;
PRINT_ERR("\tLoop %u has invalid edge reference (%d), fixed using edge %u",
sp->loopstart + j,
corner_i,
prev_e,
ml->e);
corner_edges[corner_i]);
}
else {
PRINT_ERR("\tLoop %u has invalid edge reference (%u)", sp->loopstart + j, ml->e);
PRINT_ERR("\tLoop %u has invalid edge reference (%u)", corner_i, edge_i);
sp->invalid = true;
}
}
else {
me = &medges[ml->e];
me = &medges[edge_i];
if (IS_REMOVED_EDGE(me) ||
!((me->v1 == v1 && me->v2 == v2) || (me->v1 == v2 && me->v2 == v1))) {
/* The pointed edge is invalid (tagged as removed, or vert idx mismatch),
* and we already know from previous test that a valid one exists,
* use it (if allowed)! */
if (do_fixes) {
int prev_e = ml->e;
ml->e = POINTER_AS_INT(BLI_edgehash_lookup(edge_hash, v1, v2));
int prev_e = edge_i;
corner_edges[corner_i] = POINTER_AS_INT(BLI_edgehash_lookup(edge_hash, v1, v2));
fix_flag.loops_edge = true;
PRINT_ERR(
"\tPoly %u has invalid edge reference (%d, is_removed: %d), fixed using edge "
@ -679,10 +683,10 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
sp->index,
prev_e,
IS_REMOVED_EDGE(me),
ml->e);
corner_edges[corner_i]);
}
else {
PRINT_ERR("\tPoly %u has invalid edge reference (%u)", sp->index, ml->e);
PRINT_ERR("\tPoly %u has invalid edge reference (%u)", sp->index, edge_i);
sp->invalid = true;
}
}
@ -760,10 +764,11 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
else {
/* Unused loops. */
if (prev_end < sp->loopstart) {
for (j = prev_end, ml = &mloops[prev_end]; j < sp->loopstart; j++, ml++) {
int corner_i;
for (j = prev_end, corner_i = prev_end; j < sp->loopstart; j++, corner_i++) {
PRINT_ERR("\tLoop %u is unused.", j);
if (do_fixes) {
REMOVE_LOOP_TAG(ml);
REMOVE_LOOP_TAG(corner_i);
}
}
prev_end = sp->loopstart + sp->numverts;
@ -793,10 +798,11 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
}
/* We may have some remaining unused loops to get rid of! */
if (prev_end < totloop) {
for (j = prev_end, ml = &mloops[prev_end]; j < totloop; j++, ml++) {
int corner_i;
for (j = prev_end, corner_i = prev_end; j < totloop; j++, corner_i++) {
PRINT_ERR("\tLoop %u is unused.", j);
if (do_fixes) {
REMOVE_LOOP_TAG(ml);
REMOVE_LOOP_TAG(corner_i);
}
}
}
@ -1070,7 +1076,6 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_
MutableSpan<float3> positions = me->positions_for_write();
MutableSpan<MEdge> edges = me->edges_for_write();
MutableSpan<MPoly> polys = me->polys_for_write();
MutableSpan<MLoop> loops = me->loops_for_write();
BKE_mesh_validate_arrays(me,
reinterpret_cast<float(*)[3]>(positions.data()),
@ -1079,8 +1084,9 @@ bool BKE_mesh_validate(Mesh *me, const bool do_verbose, const bool cddata_check_
edges.size(),
(MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
me->totface,
loops.data(),
loops.size(),
me->corner_verts_for_write().data(),
me->corner_edges_for_write().data(),
me->totloop,
polys.data(),
polys.size(),
me->deform_verts_for_write().data(),
@ -1121,7 +1127,6 @@ bool BKE_mesh_is_valid(Mesh *me)
MutableSpan<float3> positions = me->positions_for_write();
MutableSpan<MEdge> edges = me->edges_for_write();
MutableSpan<MPoly> polys = me->polys_for_write();
MutableSpan<MLoop> loops = me->loops_for_write();
is_valid &= BKE_mesh_validate_arrays(me,
reinterpret_cast<float(*)[3]>(positions.data()),
@ -1130,8 +1135,9 @@ bool BKE_mesh_is_valid(Mesh *me)
edges.size(),
(MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
me->totface,
loops.data(),
loops.size(),
me->corner_verts_for_write().data(),
me->corner_edges_for_write().data(),
me->totloop,
polys.data(),
polys.size(),
me->deform_verts_for_write().data(),
@ -1207,10 +1213,9 @@ void BKE_mesh_strip_loose_faces(Mesh *me)
void BKE_mesh_strip_loose_polysloops(Mesh *me)
{
MutableSpan<MPoly> polys = me->polys_for_write();
MutableSpan<MLoop> loops = me->loops_for_write();
MutableSpan<int> corner_edges = me->corner_edges_for_write();
MPoly *p;
MLoop *l;
int a, b;
/* New loops idx! */
int *new_idx = (int *)MEM_mallocN(sizeof(int) * me->totloop, __func__);
@ -1224,14 +1229,11 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
invalid = true;
}
else {
l = &loops[i];
i = stop - i;
/* If one of the poly's loops is invalid, the whole poly is invalid! */
for (; i--; l++) {
if (l->e == INVALID_LOOP_EDGE_MARKER) {
invalid = true;
break;
}
if (corner_edges.slice(p->loopstart, p->totloop)
.as_span()
.contains(INVALID_LOOP_EDGE_MARKER)) {
invalid = true;
}
}
@ -1249,10 +1251,10 @@ void BKE_mesh_strip_loose_polysloops(Mesh *me)
}
/* And now, get rid of invalid loops. */
for (a = b = 0, l = loops.data(); a < me->totloop; a++, l++) {
if (l->e != INVALID_LOOP_EDGE_MARKER) {
int corner_i = 0;
for (a = b = 0; a < me->totloop; a++, corner_i++) {
if (corner_edges[corner_i] != INVALID_LOOP_EDGE_MARKER) {
if (a != b) {
memcpy(&loops[b], l, sizeof(loops[b]));
CustomData_copy_data(&me->ldata, &me->ldata, a, b, 1);
}
new_idx[a] = b;

View File

@ -30,7 +30,7 @@ static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh)
{
const float(*positions)[3] = BKE_mesh_positions(mesh);
const MPoly *polys = BKE_mesh_polys(mesh);
const int *corner_verts = BKE_mesh_loops(mesh);
const int *corner_verts = BKE_mesh_corner_verts(mesh);
MDisps *mdisps = CustomData_get_layer(&mesh->ldata, CD_MDISPS);
const int totpoly = mesh->totpoly;

View File

@ -155,7 +155,8 @@ bool multires_reshape_context_create_from_base_mesh(MultiresReshapeContext *resh
reshape_context->base_positions = BKE_mesh_positions(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_polys(base_mesh);
reshape_context->base_loops = BKE_mesh_loops(base_mesh);
reshape_context->base_corner_verts = BKE_mesh_corner_verts(base_mesh);
reshape_context->base_corner_edges = BKE_mesh_corner_edges(base_mesh);
reshape_context->subdiv = multires_reshape_create_subdiv(NULL, object, mmd);
reshape_context->need_free_subdiv = true;
@ -192,7 +193,8 @@ bool multires_reshape_context_create_from_object(MultiresReshapeContext *reshape
reshape_context->base_positions = BKE_mesh_positions(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_polys(base_mesh);
reshape_context->base_loops = BKE_mesh_loops(base_mesh);
reshape_context->base_corner_verts = BKE_mesh_corner_verts(base_mesh);
reshape_context->base_corner_edges = BKE_mesh_corner_edges(base_mesh);
reshape_context->subdiv = multires_reshape_create_subdiv(depsgraph, object, mmd);
reshape_context->need_free_subdiv = true;
@ -224,7 +226,8 @@ bool multires_reshape_context_create_from_ccg(MultiresReshapeContext *reshape_co
reshape_context->base_positions = BKE_mesh_positions(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_polys(base_mesh);
reshape_context->base_loops = BKE_mesh_loops(base_mesh);
reshape_context->base_corner_verts = BKE_mesh_corner_verts(base_mesh);
reshape_context->base_corner_edges = BKE_mesh_corner_edges(base_mesh);
reshape_context->subdiv = subdiv_ccg->subdiv;
reshape_context->need_free_subdiv = false;
@ -271,7 +274,8 @@ bool multires_reshape_context_create_from_subdiv(MultiresReshapeContext *reshape
reshape_context->base_positions = BKE_mesh_positions(base_mesh);
reshape_context->base_edges = BKE_mesh_edges(base_mesh);
reshape_context->base_polys = BKE_mesh_polys(base_mesh);
reshape_context->base_loops = BKE_mesh_loops(base_mesh);
reshape_context->base_corner_verts = BKE_mesh_corner_verts(base_mesh);
reshape_context->base_corner_edges = BKE_mesh_corner_edges(base_mesh);
reshape_context->cd_vertex_crease = (const float *)CustomData_get_layer(&base_mesh->edata,
CD_CREASE);

View File

@ -373,7 +373,8 @@ void mesh_render_data_update_normals(MeshRenderData *mr, const eMRDataType data_
mr->vert_len,
mr->medge,
mr->edge_len,
mr->mloop,
mr->corner_verts,
mr->corner_edges,
mr->loop_normals,
mr->loop_len,
mr->mpoly,
@ -560,7 +561,8 @@ MeshRenderData *mesh_render_data_create(Object *object,
mr->positions = mr->me->positions().data();
mr->medge = BKE_mesh_edges(mr->me);
mr->mpoly = BKE_mesh_polys(mr->me);
mr->mloop = BKE_mesh_loops(mr->me);
mr->corner_verts = BKE_mesh_corner_verts(mr->me);
mr->corner_edges = BKE_mesh_corner_edges(mr->me);
mr->v_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->vdata, CD_ORIGINDEX));
mr->e_origindex = static_cast<const int *>(CustomData_get_layer(&mr->me->edata, CD_ORIGINDEX));

View File

@ -74,11 +74,9 @@ static void extract_points_iter_poly_mesh(const MeshRenderData *mr,
void *_userdata)
{
GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_userdata);
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
vert_set_mesh(elb, mr, ml->v, ml_index);
vert_set_mesh(elb, mr, mr->corner_verts[ml_index], ml_index);
}
}

View File

@ -186,7 +186,8 @@ static void fill_vertbuf_with_attribute(const MeshRenderData *mr,
const int layer_index = request.layer_index;
const MPoly *mpoly = mr->mpoly;
const MLoop *mloop = mr->mloop;
const int *corner_verts = mr->corner_verts;
const int *corner_edges = mr->corner_edges;
const AttributeType *attr_data = static_cast<const AttributeType *>(
CustomData_get_layer_n(custom_data, request.cd_type, layer_index));
@ -195,8 +196,8 @@ static void fill_vertbuf_with_attribute(const MeshRenderData *mr,
switch (request.domain) {
case ATTR_DOMAIN_POINT:
for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, vbo_data++, mloop++) {
*vbo_data = Converter::convert_value(attr_data[mloop->v]);
for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, vbo_data++) {
*vbo_data = Converter::convert_value(attr_data[corner_verts[ml_index]]);
}
break;
case ATTR_DOMAIN_CORNER:
@ -205,8 +206,8 @@ static void fill_vertbuf_with_attribute(const MeshRenderData *mr,
}
break;
case ATTR_DOMAIN_EDGE:
for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, vbo_data++, mloop++) {
*vbo_data = Converter::convert_value(attr_data[mloop->e]);
for (int ml_index = 0; ml_index < mr->loop_len; ml_index++, vbo_data++) {
*vbo_data = Converter::convert_value(attr_data[corner_edges[ml_index]]);
}
break;
case ATTR_DOMAIN_FACE:

View File

@ -151,15 +151,13 @@ static void extract_edit_data_iter_poly_mesh(const MeshRenderData *mr,
{
EditLoopData *vbo_data = *(EditLoopData **)_data;
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
EditLoopData *data = vbo_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);
BMEdge *eed = bm_original_edge_get(mr, mr->corner_verts[ml_index]);
BMVert *eve = bm_original_vert_get(mr, mr->corner_edges[ml_index]);
if (efa) {
mesh_render_data_face_flag(mr, efa, -1, data);
}

View File

@ -76,17 +76,14 @@ static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
void *_data)
{
MeshExtract_EditUVData_Data *data = static_cast<MeshExtract_EditUVData_Data *>(_data);
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
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);
BMEdge *eed = bm_original_edge_get(mr,mr->corner_verts[ml_index] );
BMVert *eve = bm_original_vert_get(mr,mr->corner_edges[ml_index] );
if (eed && eve) {
/* Loop on an edge endpoint. */
BMLoop *l = BM_face_edge_share_loop(efa, eed);
@ -99,8 +96,7 @@ static void extract_edituv_data_iter_poly_mesh(const MeshRenderData *mr,
* 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);
eed = bm_original_edge_get(mr, mr->corner_edges[l_prev]);
}
if (eed) {
/* Mapped points on an edge between two edit verts. */

View File

@ -75,20 +75,19 @@ static void extract_fdots_pos_iter_poly_mesh(const MeshRenderData *mr,
float *co = center[mp_index];
zero_v3(co);
const MLoop *mloop = mr->mloop;
const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
const int vert_i = mr->corner_verts[ml_index];
if (mr->use_subsurf_fdots) {
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
copy_v3_v3(center[mp_index], mr->positions[ml->v]);
if (BLI_BITMAP_TEST(facedot_tags, vert_i)) {
copy_v3_v3(center[mp_index], mr->positions[vert_i]);
break;
}
}
else {
add_v3_v3(center[mp_index], mr->positions[ml->v]);
add_v3_v3(center[mp_index], mr->positions[vert_i]);
}
}

View File

@ -76,12 +76,11 @@ static void extract_fdots_uv_iter_poly_mesh(const MeshRenderData *mr,
MeshExtract_FdotUV_Data *data = static_cast<MeshExtract_FdotUV_Data *>(_data);
const BLI_bitmap *facedot_tags = mr->me->runtime->subsurf_face_dot_tags;
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
const int vert_i = mr->corner_verts[ml_index];
if (mr->use_subsurf_fdots) {
if (BLI_BITMAP_TEST(facedot_tags, ml->v)) {
if (BLI_BITMAP_TEST(facedot_tags, vert_i)) {
copy_v2_v2(data->vbo_data[mp_index], data->uv_data[ml_index].uv);
}
}

View File

@ -64,16 +64,15 @@ static void extract_lnor_iter_poly_mesh(const MeshRenderData *mr,
{
const bool hidden = mr->hide_poly && mr->hide_poly[mp_index];
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
const int vert_i = mr->corner_verts[ml_index];
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_v3(mr->vert_normals[ml->v]);
*lnor_data = GPU_normal_convert_i10_v3(mr->vert_normals[vert_i]);
}
else {
*lnor_data = GPU_normal_convert_i10_v3(mr->poly_normals[mp_index]);
@ -83,7 +82,7 @@ static void extract_lnor_iter_poly_mesh(const MeshRenderData *mr,
* Only use origindex 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 (hidden ||
(mr->edit_bmesh && (mr->v_origindex) && mr->v_origindex[ml->v] == ORIGINDEX_NONE)) {
(mr->edit_bmesh && (mr->v_origindex) && mr->v_origindex[vert_i] == ORIGINDEX_NONE)) {
lnor_data->w = -1;
}
else if (mr->select_poly && mr->select_poly[mp_index]) {
@ -189,16 +188,15 @@ static void extract_lnor_hq_iter_poly_mesh(const MeshRenderData *mr,
{
const bool hidden = mr->hide_poly && mr->hide_poly[mp_index];
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
const int vert_i = mr->corner_verts[ml_index];
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) {
normal_float_to_short_v3(&lnor_data->x, mr->vert_normals[ml->v]);
normal_float_to_short_v3(&lnor_data->x, mr->vert_normals[vert_i]);
}
else {
normal_float_to_short_v3(&lnor_data->x, mr->poly_normals[mp_index]);
@ -208,7 +206,7 @@ static void extract_lnor_hq_iter_poly_mesh(const MeshRenderData *mr,
* Only use origindex 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 (hidden ||
(mr->edit_bmesh && (mr->v_origindex) && mr->v_origindex[ml->v] == ORIGINDEX_NONE)) {
(mr->edit_bmesh && (mr->v_origindex) && mr->v_origindex[vert_i] == ORIGINDEX_NONE)) {
lnor_data->w = -1;
}
else if (mr->select_poly && mr->select_poly[mp_index]) {

View File

@ -217,9 +217,9 @@ static void statvis_calc_thickness(const MeshRenderData *mr, float *r_thickness)
const MLoopTri *mlooptri = mr->mlooptri;
for (int i = 0; i < mr->tri_len; i++, mlooptri++) {
const int index = mlooptri->poly;
const float *cos[3] = {mr->positions[mr->mloop[mlooptri->tri[0]].v],
mr->positions[mr->mloop[mlooptri->tri[1]].v],
mr->positions[mr->mloop[mlooptri->tri[2]].v]};
const float *cos[3] = {mr->positions[mr->corner_verts[mlooptri->tri[0]]],
mr->positions[mr->corner_verts[mlooptri->tri[1]]],
mr->positions[mr->corner_verts[mlooptri->tri[2]]]};
float ray_co[3];
float ray_no[3];
@ -260,7 +260,7 @@ static void statvis_calc_thickness(const MeshRenderData *mr, float *r_thickness)
struct BVHTree_OverlapData {
const float3 *positions;
const MLoop *loops;
const int *corner_verts;
const MLoopTri *mlooptri;
float epsilon;
};
@ -276,12 +276,12 @@ static bool bvh_overlap_cb(void *userdata, int index_a, int index_b, int /*threa
return false;
}
const float *tri_a_co[3] = {data->positions[data->loops[tri_a->tri[0]].v],
data->positions[data->loops[tri_a->tri[1]].v],
data->positions[data->loops[tri_a->tri[2]].v]};
const float *tri_b_co[3] = {data->positions[data->loops[tri_b->tri[0]].v],
data->positions[data->loops[tri_b->tri[1]].v],
data->positions[data->loops[tri_b->tri[2]].v]};
const float *tri_a_co[3] = {data->positions[data->corner_verts[tri_a->tri[0]]],
data->positions[data->corner_verts[tri_a->tri[1]]],
data->positions[data->corner_verts[tri_a->tri[2]]]};
const float *tri_b_co[3] = {data->positions[data->corner_verts[tri_b->tri[0]]],
data->positions[data->corner_verts[tri_b->tri[1]]],
data->positions[data->corner_verts[tri_b->tri[2]]]};
float ix_pair[2][3];
int verts_shared = 0;
@ -343,7 +343,7 @@ static void statvis_calc_intersect(const MeshRenderData *mr, float *r_intersect)
struct BVHTree_OverlapData data = {nullptr};
data.positions = mr->positions;
data.loops = mr->mloop;
data.corner_verts = mr->corner_verts;
data.mlooptri = mr->mlooptri;
data.epsilon = BLI_bvhtree_get_epsilon(tree);
@ -449,14 +449,14 @@ static void statvis_calc_distort(const MeshRenderData *mr, float *r_distort)
fac = 0.0f;
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];
const int corner_prev = mp->loopstart + (i - 1) % mp->totloop;
const int corner_curr = mp->loopstart + (i + 0) % mp->totloop;
const int corner_next = mp->loopstart + (i + 1) % mp->totloop;
float no_corner[3];
normal_tri_v3(no_corner,
mr->positions[l_prev->v],
mr->positions[l_curr->v],
mr->positions[l_next->v]);
mr->positions[mr->corner_verts[corner_prev]],
mr->positions[mr->corner_verts[corner_curr]],
mr->positions[mr->corner_verts[corner_next]]);
/* simple way to detect (what is most likely) concave */
if (dot_v3v3(f_no, no_corner) < 0.0f) {
negate_v3(no_corner);
@ -532,11 +532,11 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp)
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 int vert_curr = mr->corner_verts[mp->loopstart + (i + 0) % mp->totloop];
const int vert_next = mr->corner_verts[mp->loopstart + (i + 1) % mp->totloop];
float angle;
void **pval;
bool value_is_init = BLI_edgehash_ensure_p(eh, l_curr->v, l_next->v, &pval);
bool value_is_init = BLI_edgehash_ensure_p(eh, vert_curr, vert_next, &pval);
if (!value_is_init) {
*pval = (void *)mr->poly_normals[mp_index];
/* non-manifold edge, yet... */
@ -547,7 +547,7 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp)
const float *f2_no = static_cast<const float *>(*pval);
angle = angle_normalized_v3v3(f1_no, f2_no);
angle = is_edge_convex_v3(
mr->positions[l_curr->v], mr->positions[l_next->v], f1_no, f2_no) ?
mr->positions[vert_curr], mr->positions[vert_next], f1_no, f2_no) ?
angle :
-angle;
/* Tag as manifold. */
@ -557,8 +557,8 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp)
/* non-manifold edge */
angle = DEG2RADF(90.0f);
}
float *col1 = &vert_angles[l_curr->v];
float *col2 = &vert_angles[l_next->v];
float *col1 = &vert_angles[vert_curr];
float *col2 = &vert_angles[vert_next];
*col1 = max_ff(*col1, angle);
*col2 = max_ff(*col2, angle);
}
@ -579,9 +579,9 @@ static void statvis_calc_sharp(const MeshRenderData *mr, float *r_sharp)
BLI_edgehashIterator_free(ehi);
BLI_edgehash_free(eh, nullptr);
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);
for (int l_index = 0; l_index < mr->loop_len; l_index++) {
const int vert_i = mr->corner_verts[l_index];
r_sharp[l_index] = sharp_remap(vert_angles[vert_i], min, max, minmax_irange);
}
}

View File

@ -66,13 +66,12 @@ static void extract_orco_iter_poly_mesh(const MeshRenderData *mr,
const int /*mp_index*/,
void *data)
{
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
const int vert_i = mr->corner_verts[ml_index];
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]);
copy_v3_v3(loop_orco, orco_data->orco[vert_i]);
loop_orco[3] = 0.0; /* Tag as not a generic attribute. */
}
}

View File

@ -89,21 +89,20 @@ static void extract_pos_nor_iter_poly_mesh(const MeshRenderData *mr,
MeshExtract_PosNor_Data *data = static_cast<MeshExtract_PosNor_Data *>(_data);
const bool poly_hidden = mr->hide_poly && mr->hide_poly[mp_index];
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
const int vert_i = mr->corner_verts[ml_index];
PosNorLoop *vert = &data->vbo_data[ml_index];
const bool vert_hidden = mr->hide_vert && mr->hide_vert[ml->v];
copy_v3_v3(vert->pos, mr->positions[ml->v]);
vert->nor = data->normals[ml->v].low;
const bool vert_hidden = mr->hide_vert && mr->hide_vert[vert_i];
copy_v3_v3(vert->pos, mr->positions[vert_i]);
vert->nor = data->normals[vert_i].low;
/* Flag for paint mode overlay. */
if (poly_hidden || vert_hidden ||
((mr->v_origindex) && (mr->v_origindex[ml->v] == ORIGINDEX_NONE))) {
((mr->v_origindex) && (mr->v_origindex[vert_i] == ORIGINDEX_NONE))) {
vert->nor.w = -1;
}
else if (mr->select_vert && mr->select_vert[ml->v]) {
else if (mr->select_vert && mr->select_vert[vert_i]) {
vert->nor.w = 1;
}
else {
@ -464,22 +463,21 @@ static void extract_pos_nor_hq_iter_poly_mesh(const MeshRenderData *mr,
MeshExtract_PosNorHQ_Data *data = static_cast<MeshExtract_PosNorHQ_Data *>(_data);
const bool poly_hidden = mr->hide_poly && mr->hide_poly[mp - mr->mpoly];
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
const int vert_i = mr->corner_verts[ml_index];
const bool vert_hidden = mr->hide_vert && mr->hide_vert[ml->v];
const bool vert_hidden = mr->hide_vert && mr->hide_vert[vert_i];
PosNorHQLoop *vert = &data->vbo_data[ml_index];
copy_v3_v3(vert->pos, mr->positions[ml->v]);
copy_v3_v3_short(vert->nor, data->normals[ml->v].high);
copy_v3_v3(vert->pos, mr->positions[vert_i]);
copy_v3_v3_short(vert->nor, data->normals[vert_i].high);
/* Flag for paint mode overlay. */
if (poly_hidden || vert_hidden ||
((mr->v_origindex) && (mr->v_origindex[ml->v] == ORIGINDEX_NONE))) {
((mr->v_origindex) && (mr->v_origindex[vert_i] == ORIGINDEX_NONE))) {
vert->nor[3] = -1;
}
else if (mr->select_vert && mr->select_vert[ml->v]) {
else if (mr->select_vert && mr->select_vert[vert_i]) {
vert->nor[3] = 1;
}
else {

View File

@ -56,7 +56,6 @@ static void extract_sculpt_data_init(const MeshRenderData *mr,
};
gpuSculptData *vbo_data = (gpuSculptData *)GPU_vertbuf_get_data(vbo);
const MLoop *loops = (const MLoop *)CustomData_get_layer(cd_ldata, CD_MLOOP);
if (mr->extract_type == MR_EXTRACT_BMESH) {
int cd_mask_ofs = CustomData_get_offset(cd_vdata, CD_PAINT_MASK);

View File

@ -125,11 +125,10 @@ static void extract_edge_idx_iter_poly_mesh(const MeshRenderData *mr,
const int /*mp_index*/,
void *data)
{
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
(*(int32_t **)data)[ml_index] = (mr->e_origindex) ? mr->e_origindex[ml->e] : ml->e;
const int edge_i = mr->corner_edges[ml_index];
(*(int32_t **)data)[ml_index] = (mr->e_origindex) ? mr->e_origindex[edge_i] : edge_i;
}
}
@ -138,11 +137,10 @@ static void extract_vert_idx_iter_poly_mesh(const MeshRenderData *mr,
const int /*mp_index*/,
void *data)
{
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
(*(int32_t **)data)[ml_index] = (mr->v_origindex) ? mr->v_origindex[ml->v] : ml->v;
const int vert_i = mr->corner_verts[ml_index];
(*(int32_t **)data)[ml_index] = (mr->v_origindex) ? mr->v_origindex[vert_i] : vert_i;
}
}

View File

@ -138,12 +138,11 @@ static void extract_weights_iter_poly_mesh(const MeshRenderData *mr,
void *_data)
{
MeshExtract_Weight_Data *data = static_cast<MeshExtract_Weight_Data *>(_data);
const MLoop *mloop = mr->mloop;
const int ml_index_end = mp->loopstart + mp->totloop;
for (int ml_index = mp->loopstart; ml_index < ml_index_end; ml_index += 1) {
const MLoop *ml = &mloop[ml_index];
const int vert_i = mr->corner_verts[ml_index];
if (data->dvert != nullptr) {
const MDeformVert *dvert = &data->dvert[ml->v];
const MDeformVert *dvert = &data->dvert[vert_i];
data->vbo_data[ml_index] = evaluate_vertex_weight(dvert, data->wstate);
}
else {

View File

@ -75,7 +75,7 @@ struct LaplacianSystem {
struct HeatWeighting {
const MLoopTri *mlooptri;
const MLoop *mloop; /* needed to find vertices by index */
const int *corner_verts; /* needed to find vertices by index */
int verts_num;
int tris_num;
float (*verts)[3]; /* vertex coordinates */
@ -378,14 +378,14 @@ static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTr
{
BVHCallbackUserData *data = (struct BVHCallbackUserData *)userdata;
const MLoopTri *lt = &data->sys->heat.mlooptri[index];
const MLoop *mloop = data->sys->heat.mloop;
const int *corner_verts = data->sys->heat.corner_verts;
float(*verts)[3] = data->sys->heat.verts;
const float *vtri_co[3];
float dist_test;
vtri_co[0] = verts[mloop[lt->tri[0]].v];
vtri_co[1] = verts[mloop[lt->tri[1]].v];
vtri_co[2] = verts[mloop[lt->tri[2]].v];
vtri_co[0] = verts[corner_verts[lt->tri[0]]];
vtri_co[1] = verts[corner_verts[lt->tri[1]]];
vtri_co[2] = verts[corner_verts[lt->tri[2]]];
#ifdef USE_KDOPBVH_WATERTIGHT
if (isect_ray_tri_watertight_v3(
@ -410,7 +410,7 @@ static void bvh_callback(void *userdata, int index, const BVHTreeRay *ray, BVHTr
static void heat_ray_tree_create(LaplacianSystem *sys)
{
const MLoopTri *looptri = sys->heat.mlooptri;
const MLoop *mloop = sys->heat.mloop;
const int *corner_verts = sys->heat.corner_verts;
float(*verts)[3] = sys->heat.verts;
int tris_num = sys->heat.tris_num;
int verts_num = sys->heat.verts_num;
@ -424,9 +424,9 @@ static void heat_ray_tree_create(LaplacianSystem *sys)
float bb[6];
int vtri[3];
vtri[0] = mloop[lt->tri[0]].v;
vtri[1] = mloop[lt->tri[1]].v;
vtri[2] = mloop[lt->tri[2]].v;
vtri[0] = corner_verts[lt->tri[0]];
vtri[1] = corner_verts[lt->tri[1]];
vtri[2] = corner_verts[lt->tri[2]];
INIT_MINMAX(bb, bb + 3);
minmax_v3v3_v3(bb, bb + 3, verts[vtri[0]]);
@ -575,7 +575,7 @@ static void heat_calc_vnormals(LaplacianSystem *sys)
static void heat_laplacian_create(LaplacianSystem *sys)
{
const MLoopTri *mlooptri = sys->heat.mlooptri, *lt;
const MLoop *mloop = sys->heat.mloop;
const int *corner_verts = sys->heat.corner_verts;
int tris_num = sys->heat.tris_num;
int verts_num = sys->heat.verts_num;
int a;
@ -592,9 +592,9 @@ static void heat_laplacian_create(LaplacianSystem *sys)
for (a = 0, lt = mlooptri; a < tris_num; a++, lt++) {
int vtri[3];
vtri[0] = mloop[lt->tri[0]].v;
vtri[1] = mloop[lt->tri[1]].v;
vtri[2] = mloop[lt->tri[2]].v;
vtri[0] = corner_verts[lt->tri[0]];
vtri[1] = corner_verts[lt->tri[1]];
vtri[2] = corner_verts[lt->tri[2]];
laplacian_add_triangle(sys, UNPACK3(vtri));
}
@ -646,7 +646,6 @@ void heat_bone_weighting(Object *ob,
LaplacianSystem *sys;
MLoopTri *mlooptri;
const MPoly *mp;
const MLoop *ml;
float solution, weight;
int *vertsflipped = NULL, *mask = NULL;
int a, tris_num, j, bbone, firstsegment, lastsegment;
@ -654,7 +653,7 @@ void heat_bone_weighting(Object *ob,
const float(*mesh_positions)[3] = BKE_mesh_positions(me);
const MPoly *polys = BKE_mesh_polys(me);
const MLoop *loops = BKE_mesh_loops(me);
const int *corner_verts = BKE_mesh_corner_verts(me);
bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
bool use_face_sel = (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
@ -673,8 +672,9 @@ void heat_bone_weighting(Object *ob,
&me->vdata, CD_PROP_BOOL, ".select_vert");
if (select_vert) {
for (a = 0, mp = polys; a < me->totpoly; mp++, a++) {
for (j = 0, ml = loops + mp->loopstart; j < mp->totloop; j++, ml++) {
mask[ml->v] = select_vert[ml->v];
for (j = 0; j < mp->totloop; j++) {
const int vert_i = corner_verts[mp->loopstart + j];
mask[vert_i] = select_vert[vert_i];
}
}
}
@ -685,8 +685,9 @@ void heat_bone_weighting(Object *ob,
if (select_poly) {
for (a = 0, mp = polys; a < me->totpoly; mp++, a++) {
if (select_poly[a]) {
for (j = 0, ml = loops + mp->loopstart; j < mp->totloop; j++, ml++) {
mask[ml->v] = 1;
for (j = 0; j < mp->totloop; j++) {
const int vert_i = corner_verts[mp->loopstart + j];
mask[vert_i] = 1;
}
}
}
@ -700,10 +701,10 @@ void heat_bone_weighting(Object *ob,
sys->heat.tris_num = poly_to_tri_count(me->totpoly, me->totloop);
mlooptri = MEM_mallocN(sizeof(*sys->heat.mlooptri) * sys->heat.tris_num, __func__);
BKE_mesh_recalc_looptri(loops, polys, mesh_positions, me->totloop, me->totpoly, mlooptri);
BKE_mesh_recalc_looptri(corner_verts, polys, mesh_positions, me->totloop, me->totpoly, mlooptri);
sys->heat.mlooptri = mlooptri;
sys->heat.mloop = loops;
sys->heat.corner_verts = corner_verts;
sys->heat.verts_num = me->totvert;
sys->heat.verts = verts;
sys->heat.root = root;
@ -921,7 +922,7 @@ typedef struct MeshDeformBind {
/* avoid DM function calls during intersections */
struct {
const MPoly *mpoly;
const MLoop *mloop;
const int *corner_verts;
const MLoopTri *looptri;
const float (*poly_nors)[3];
} cagemesh_cache;
@ -952,7 +953,7 @@ static void harmonic_ray_callback(void *userdata,
{
struct MeshRayCallbackData *data = userdata;
MeshDeformBind *mdb = data->mdb;
const MLoop *mloop = mdb->cagemesh_cache.mloop;
const int *corner_verts = mdb->cagemesh_cache.corner_verts;
const MLoopTri *looptri = mdb->cagemesh_cache.looptri, *lt;
const float(*poly_nors)[3] = mdb->cagemesh_cache.poly_nors;
MeshDeformIsect *isec = data->isec;
@ -961,9 +962,9 @@ static void harmonic_ray_callback(void *userdata,
lt = &looptri[index];
face[0] = mdb->cagecos[mloop[lt->tri[0]].v];
face[1] = mdb->cagecos[mloop[lt->tri[1]].v];
face[2] = mdb->cagecos[mloop[lt->tri[2]].v];
face[0] = mdb->cagecos[corner_verts[lt->tri[0]]];
face[1] = mdb->cagecos[corner_verts[lt->tri[1]]];
face[2] = mdb->cagecos[corner_verts[lt->tri[2]]];
bool isect_ray_tri = isect_ray_tri_watertight_v3(
ray->origin, ray->isect_precalc, UNPACK3(face), &dist, NULL);
@ -1027,7 +1028,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb,
harmonic_ray_callback,
&data,
BVH_RAYCAST_WATERTIGHT) != -1) {
const MLoop *mloop = mdb->cagemesh_cache.mloop;
const int *corner_verts = mdb->cagemesh_cache.corner_verts;
const MLoopTri *lt = &mdb->cagemesh_cache.looptri[hit.index];
const MPoly *mp = &mdb->cagemesh_cache.mpoly[lt->poly];
const float(*cagecos)[3] = mdb->cagecos;
@ -1050,7 +1051,7 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb,
/* compute mean value coordinates for interpolation */
for (int i = 0; i < mp->totloop; i++) {
copy_v3_v3(mp_cagecos[i], cagecos[mloop[mp->loopstart + i].v]);
copy_v3_v3(mp_cagecos[i], cagecos[corner_verts[mp->loopstart + i]]);
}
interp_weights_poly_v3(isect->poly_weights, mp_cagecos, mp->totloop, isect->co);
@ -1216,11 +1217,11 @@ static float meshdeform_boundary_phi(const MeshDeformBind *mdb,
const MDefBoundIsect *isect,
int cagevert)
{
const MLoop *mloop = mdb->cagemesh_cache.mloop;
const int *corner_verts = mdb->cagemesh_cache.corner_verts;
const MPoly *mp = &mdb->cagemesh_cache.mpoly[isect->poly_index];
for (int i = 0; i < mp->totloop; i++) {
if (mloop[mp->loopstart + i].v == cagevert) {
if (corner_verts[mp->loopstart + i] == cagevert) {
return isect->poly_weights[i];
}
}
@ -1617,7 +1618,7 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin
{
Mesh *me = mdb->cagemesh;
mdb->cagemesh_cache.mpoly = BKE_mesh_polys(me);
mdb->cagemesh_cache.mloop = BKE_mesh_loops(me);
mdb->cagemesh_cache.corner_verts = BKE_mesh_corner_verts(me);
mdb->cagemesh_cache.looptri = BKE_mesh_runtime_looptri_ensure(me);
mdb->cagemesh_cache.poly_nors = BKE_mesh_poly_normals_ensure(me);
}

View File

@ -975,7 +975,7 @@ static bool bake_targets_init_vertex_colors(Main *bmain,
}
static int find_original_loop(const MPoly *orig_polys,
const MLoop *orig_loops,
const int *orig_corner_verts,
const int *vert_origindex,
const int *poly_origindex,
const int poly_eval,
@ -992,9 +992,9 @@ static int find_original_loop(const MPoly *orig_polys,
/* Find matching loop with original vertex in original polygon. */
const MPoly *mpoly_orig = orig_polys + poly_orig;
const MLoop *mloop_orig = orig_loops + mpoly_orig->loopstart;
for (int j = 0; j < mpoly_orig->totloop; ++j, ++mloop_orig) {
if (mloop_orig->v == vert_orig) {
const int *poly_verts_orig = orig_corner_verts + mpoly_orig->loopstart;
for (int j = 0; j < mpoly_orig->totloop; ++j) {
if (poly_verts_orig[j] == vert_orig) {
return mpoly_orig->loopstart + j;
}
}
@ -1029,8 +1029,8 @@ static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets,
const int tottri = poly_to_tri_count(me_eval->totpoly, me_eval->totloop);
MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__);
const MLoop *loops = BKE_mesh_loops(me_eval);
BKE_mesh_recalc_looptri(loops,
const int *corner_verts = BKE_mesh_corner_verts(me_eval);
BKE_mesh_recalc_looptri(corner_verts,
BKE_mesh_polys(me_eval),
BKE_mesh_positions(me_eval),
me_eval->totloop,
@ -1041,19 +1041,19 @@ static void bake_targets_populate_pixels_color_attributes(BakeTargets *targets,
const int *vert_origindex = CustomData_get_layer(&me_eval->vdata, CD_ORIGINDEX);
const int *poly_origindex = CustomData_get_layer(&me_eval->pdata, CD_ORIGINDEX);
const MPoly *orig_polys = BKE_mesh_polys(me);
const MLoop *orig_loops = BKE_mesh_loops(me);
const int *orig_corner_verts = BKE_mesh_corner_verts(me);
for (int i = 0; i < tottri; i++) {
const MLoopTri *lt = &looptri[i];
for (int j = 0; j < 3; j++) {
uint l = lt->tri[j];
uint v = loops[l].v;
const int v = corner_verts[l];
/* Map back to original loop if there are modifiers. */
if (vert_origindex != NULL && poly_origindex != NULL) {
l = find_original_loop(
orig_polys, orig_loops, vert_origindex, poly_origindex, lt->poly, v);
orig_polys, orig_corner_verts, vert_origindex, poly_origindex, lt->poly, v);
if (l == ORIGINDEX_NONE || l >= me->totloop) {
continue;
}
@ -1147,9 +1147,9 @@ static bool bake_targets_output_vertex_colors(BakeTargets *targets, Object *ob)
int *num_loops_for_vertex = MEM_callocN(sizeof(int) * me->totvert, "num_loops_for_vertex");
memset(mcol, 0, sizeof(MPropCol) * me->totvert);
const MLoop *mloop = BKE_mesh_loops(me);
for (int i = 0; i < totloop; i++, mloop++) {
const int v = mloop->v;
const int *corner_verts = BKE_mesh_corner_verts(me);
for (int i = 0; i < totloop; i++) {
const int v = corner_verts[i];
bake_result_add_to_rgba(mcol[v].color, &result[i * channels_num], channels_num);
num_loops_for_vertex[v]++;
}

View File

@ -1186,7 +1186,7 @@ static void sculpt_gesture_trim_geometry_generate(SculptGestureContext *sgcontex
/* Write the front face triangle indices. */
MPoly *polys = BKE_mesh_polys_for_write(trim_operation->mesh);
int *corner_verts = BKE_mesh_loops_for_write(trim_operation->mesh);
int *corner_verts = BKE_mesh_corner_verts_for_write(trim_operation->mesh);
MPoly *mp = polys;
int corner_i = 0;
for (int i = 0; i < tot_tris_face; i++, mp++, corner_i += 3) {

View File

@ -1474,7 +1474,8 @@ struct EdgeFeatData {
const MLoopTri *mlooptri;
const int *material_indices;
blender::Span<MEdge> edges;
blender::Span<MLoop> loops;
blender::Span<int> corner_verts;
blender::Span<int> corner_edges;
blender::Span<MPoly> polys;
LineartTriangle *tri_array;
LineartVert *v_array;
@ -1678,8 +1679,11 @@ static void lineart_identify_mlooptri_feature_edges(void *__restrict userdata,
}
int real_edges[3];
BKE_mesh_looptri_get_real_edges(
e_feat_data->edges.data(), e_feat_data->loops.data(), &mlooptri[i / 3], real_edges);
BKE_mesh_looptri_get_real_edges(e_feat_data->edges.data(),
e_feat_data->corner_verts.data(),
e_feat_data->corner_edges.data(),
&mlooptri[i / 3],
real_edges);
if (real_edges[i % 3] >= 0) {
const MEdge *medge = &e_feat_data->edges[real_edges[i % 3]];
@ -1785,7 +1789,7 @@ static void lineart_triangle_adjacent_assign(LineartTriangle *tri,
struct TriData {
LineartObjectInfo *ob_info;
blender::Span<blender::float3> positions;
blender::Span<MLoop> loops;
blender::Span<int> corner_verts;
const MLoopTri *mlooptri;
const int *material_indices;
LineartVert *vert_arr;
@ -1801,7 +1805,7 @@ static void lineart_load_tri_task(void *__restrict userdata,
TriData *tri_task_data = (TriData *)userdata;
LineartObjectInfo *ob_info = tri_task_data->ob_info;
const blender::Span<blender::float3> positions = tri_task_data->positions;
const blender::Span<MLoop> loops = tri_task_data->loops;
const blender::Span<int> corner_verts = tri_task_data->corner_verts;
const MLoopTri *mlooptri = &tri_task_data->mlooptri[i];
const int *material_indices = tri_task_data->material_indices;
LineartVert *vert_arr = tri_task_data->vert_arr;
@ -1809,9 +1813,9 @@ static void lineart_load_tri_task(void *__restrict userdata,
tri = (LineartTriangle *)(((uchar *)tri) + tri_task_data->lineart_triangle_size * i);
int v1 = loops[mlooptri->tri[0]].v;
int v2 = loops[mlooptri->tri[1]].v;
int v3 = loops[mlooptri->tri[2]].v;
int v1 = corner_verts[mlooptri->tri[0]];
int v2 = corner_verts[mlooptri->tri[1]];
int v3 = corner_verts[mlooptri->tri[2]];
tri->v[0] = &vert_arr[v1];
tri->v[1] = &vert_arr[v2];
@ -1860,7 +1864,7 @@ struct EdgeNeighborData {
LineartEdgeNeighbor *edge_nabr;
LineartAdjacentEdge *adj_e;
const MLoopTri *mlooptri;
const MLoop *mloop;
const int *corner_verts;
};
static void lineart_edge_neighbor_init_task(void *__restrict userdata,
@ -1871,11 +1875,11 @@ static void lineart_edge_neighbor_init_task(void *__restrict userdata,
LineartAdjacentEdge *adj_e = &en_data->adj_e[i];
const MLoopTri *looptri = &en_data->mlooptri[i / 3];
LineartEdgeNeighbor *edge_nabr = &en_data->edge_nabr[i];
const MLoop *mloop = en_data->mloop;
const int *corner_verts = en_data->corner_verts;
adj_e->e = i;
adj_e->v1 = mloop[looptri->tri[i % 3]].v;
adj_e->v2 = mloop[looptri->tri[(i + 1) % 3]].v;
adj_e->v1 = corner_verts[looptri->tri[i % 3]];
adj_e->v2 = corner_verts[looptri->tri[(i + 1) % 3]];
if (adj_e->v1 > adj_e->v2) {
SWAP(uint32_t, adj_e->v1, adj_e->v2);
}
@ -1903,7 +1907,7 @@ static LineartEdgeNeighbor *lineart_build_edge_neighbor(Mesh *me, int total_edge
en_data.adj_e = adj_e;
en_data.edge_nabr = edge_nabr;
en_data.mlooptri = BKE_mesh_runtime_looptri_ensure(me);
en_data.mloop = BKE_mesh_loops(me);
en_data.corner_verts = me->corner_verts().data();
BLI_task_parallel_range(0, total_edges, &en_data, lineart_edge_neighbor_init_task, &en_settings);
@ -2075,7 +2079,8 @@ static void lineart_geometry_object_load(LineartObjectInfo *ob_info,
edge_feat_data.material_indices = material_indices;
edge_feat_data.edges = me->edges();
edge_feat_data.polys = me->polys();
edge_feat_data.loops = me->loops();
edge_feat_data.corner_verts = me->corner_verts();
edge_feat_data.corner_edges = me->corner_edges();
edge_feat_data.edge_nabr = lineart_build_edge_neighbor(me, total_edges);
edge_feat_data.tri_array = la_tri_arr;
edge_feat_data.v_array = la_v_arr;

View File

@ -178,14 +178,6 @@ void BKE_mesh_calc_poly_normal(const struct MPoly * /*mpoly*/,
BLI_assert_unreachable();
}
void BKE_mesh_looptri_get_real_edges(const struct MEdge * /*edges*/,
const struct MLoop * /*loops*/,
const struct MLoopTri * /*looptri*/,
int UNUSED(r_edges[3]))
{
BLI_assert_unreachable();
}
/** \} */
/* -------------------------------------------------------------------- */

View File

@ -615,9 +615,8 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh,
VCOLDataWrapper vcol(collada_mesh->getColors());
MutableSpan<MPoly> polys = me->polys_for_write();
MutableSpan<MLoop> loops = me->loops_for_write();
MutableSpan<int> corner_verts = me->corner_verts_for_write();
MPoly *mpoly = polys.data();
MLoop *mloop = loops.data();
int loop_index = 0;
MaterialIdPrimitiveArrayMap mat_prim_map;
@ -660,7 +659,8 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh,
/* For each triangle store indices of its 3 vertices */
uint triangle_vertex_indices[3] = {
first_vertex, position_indices[1], position_indices[2]};
set_poly_indices(mpoly, mloop, loop_index, triangle_vertex_indices, 3);
set_poly_indices(
mpoly, &corner_verts[loop_index], loop_index, triangle_vertex_indices, 3);
if (mp_has_normals) { /* vertex normals, same implementation as for the triangles */
/* The same for vertices normals. */
@ -675,7 +675,6 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh,
if (material_indices) {
material_indices++;
}
mloop += 3;
loop_index += 3;
prim.totpoly++;
}
@ -708,7 +707,8 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh,
continue; /* TODO: add support for holes */
}
bool broken_loop = set_poly_indices(mpoly, mloop, loop_index, position_indices, vcount);
bool broken_loop = set_poly_indices(
mpoly, &corner_verts[loop_index], loop_index, position_indices, vcount);
if (broken_loop) {
invalid_loop_holes += 1;
}
@ -778,7 +778,6 @@ void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh,
if (material_indices) {
material_indices++;
}
mloop += vcount;
loop_index += vcount;
start_index += vcount;
prim.totpoly++;
@ -900,8 +899,8 @@ std::string *MeshImporter::get_geometry_name(const std::string &mesh_name)
static bool bc_has_out_of_bound_indices(Mesh *me)
{
for (const MLoop &loop : me->loops()) {
if (loop.v >= me->totvert) {
for (const int vert_i : me->corner_verts()) {
if (vert_i >= me->totvert) {
return true;
}
}

View File

@ -220,8 +220,8 @@ enum {
* It may also be useful to check whether or not two vertices of a triangle
* form an edge in the underlying mesh.
*
* This can be done by checking the edge of the referenced loop (#MLoop.e),
* the winding of the #MLoopTri and the #MLoop's will always match,
* This can be done by checking the edge of the referenced corner,
* the winding of the #MLoopTri and the corners's will always match,
* however the order of vertices in the edge is undefined.
*
* \code{.c}
@ -477,8 +477,8 @@ enum {
* \{ */
/**
* Used in Blender pre 2.63, See #MLoop, #MPoly for face data stored in the blend file.
* Use for reading old files and in a handful of cases which should be removed eventually.
* Used in Blender pre 2.63, See #Mesh::corner_verts(), #MPoly for face data stored in the blend
* file. Use for reading old files and in a handful of cases which should be removed eventually.
*/
typedef struct MFace {
unsigned int v1, v2, v3, v4;

View File

@ -395,8 +395,8 @@ static int rna_MeshPolygon_index_get(PointerRNA *ptr)
static int rna_MeshLoop_index_get(PointerRNA *ptr)
{
const Mesh *mesh = rna_mesh(ptr);
const MLoop *mloop = (MLoop *)ptr->data;
const int index = (int)(mloop - BKE_mesh_loops(mesh));
const int *corner_vert = (const int *)ptr->data;
const int index = (int)(corner_vert - BKE_mesh_corner_verts(mesh));
BLI_assert(index >= 0);
BLI_assert(index < mesh->totloop);
return index;
@ -560,6 +560,30 @@ static void rna_MEdge_crease_set(PointerRNA *ptr, float value)
values[index] = clamp_f(value, 0.0f, 1.0f);
}
static int rna_MeshLoop_vertex_index_get(PointerRNA *ptr)
{
return *(int *)ptr->data;
}
static void rna_MeshLoop_vertex_index_set(PointerRNA *ptr, int value)
{
*(int *)ptr->data = value;
}
static int rna_MeshLoop_edge_index_get(PointerRNA *ptr)
{
const Mesh *me = rna_mesh(ptr);
const int index = rna_MeshLoop_index_get(ptr);
return BKE_mesh_corner_edges(me)[index];
}
static void rna_MeshLoop_edge_index_set(PointerRNA *ptr, int value)
{
const Mesh *me = rna_mesh(ptr);
const int index = rna_MeshLoop_index_get(ptr);
BKE_mesh_corner_edges_for_write(me)[index] = value;
}
static void rna_MeshLoop_normal_get(PointerRNA *ptr, float *values)
{
Mesh *me = rna_mesh(ptr);
@ -629,8 +653,8 @@ static void rna_MeshPolygon_normal_get(PointerRNA *ptr, float *values)
Mesh *me = rna_mesh(ptr);
MPoly *mp = (MPoly *)ptr->data;
const float(*positions)[3] = BKE_mesh_positions(me);
const MLoop *loops = BKE_mesh_loops(me);
BKE_mesh_calc_poly_normal(mp, loops + mp->loopstart, positions, values);
const int *corner_verts = BKE_mesh_corner_verts(me);
BKE_mesh_calc_poly_normal(mp, corner_verts + mp->loopstart, positions, values);
}
static bool rna_MeshPolygon_hide_get(PointerRNA *ptr)
@ -706,8 +730,8 @@ static void rna_MeshPolygon_center_get(PointerRNA *ptr, float *values)
Mesh *me = rna_mesh(ptr);
MPoly *mp = (MPoly *)ptr->data;
const float(*positions)[3] = BKE_mesh_positions(me);
const MLoop *loops = BKE_mesh_loops(me);
BKE_mesh_calc_poly_center(mp, loops + mp->loopstart, positions, values);
const int *corner_verts = BKE_mesh_corner_verts(me);
BKE_mesh_calc_poly_center(mp, corner_verts + mp->loopstart, positions, values);
}
static float rna_MeshPolygon_area_get(PointerRNA *ptr)
@ -715,15 +739,16 @@ static float rna_MeshPolygon_area_get(PointerRNA *ptr)
Mesh *me = (Mesh *)ptr->owner_id;
MPoly *mp = (MPoly *)ptr->data;
const float(*positions)[3] = BKE_mesh_positions(me);
const MLoop *loops = BKE_mesh_loops(me);
return BKE_mesh_calc_poly_area(mp, loops + mp->loopstart, positions);
const int *corner_verts = BKE_mesh_corner_verts(me);
return BKE_mesh_calc_poly_area(mp, corner_verts + mp->loopstart, positions);
}
static void rna_MeshPolygon_flip(ID *id, MPoly *mp)
{
Mesh *me = (Mesh *)id;
MLoop *loops = BKE_mesh_loops_for_write(me);
BKE_mesh_polygon_flip(mp, loops, &me->ldata);
int *corner_verts = BKE_mesh_corner_verts_for_write(me);
int *corner_edges = BKE_mesh_corner_edges_for_write(me);
BKE_mesh_polygon_flip(mp, corner_verts, corner_edges, &me->ldata);
BKE_mesh_tessface_clear(me);
BKE_mesh_runtime_clear_geometry(me);
}
@ -731,11 +756,11 @@ static void rna_MeshPolygon_flip(ID *id, MPoly *mp)
static void rna_MeshLoopTriangle_verts_get(PointerRNA *ptr, int *values)
{
Mesh *me = rna_mesh(ptr);
const MLoop *loops = BKE_mesh_loops(me);
const int *corner_verts = BKE_mesh_corner_verts(me);
MLoopTri *lt = (MLoopTri *)ptr->data;
values[0] = loops[lt->tri[0]].v;
values[1] = loops[lt->tri[1]].v;
values[2] = loops[lt->tri[2]].v;
values[0] = corner_verts[lt->tri[0]];
values[1] = corner_verts[lt->tri[1]];
values[2] = corner_verts[lt->tri[2]];
}
static void rna_MeshLoopTriangle_normal_get(PointerRNA *ptr, float *values)
@ -743,10 +768,10 @@ static void rna_MeshLoopTriangle_normal_get(PointerRNA *ptr, float *values)
Mesh *me = rna_mesh(ptr);
MLoopTri *lt = (MLoopTri *)ptr->data;
const float(*positions)[3] = BKE_mesh_positions(me);
const MLoop *loops = BKE_mesh_loops(me);
uint v1 = loops[lt->tri[0]].v;
uint v2 = loops[lt->tri[1]].v;
uint v3 = loops[lt->tri[2]].v;
const int *corner_verts = BKE_mesh_corner_verts(me);
const int v1 = corner_verts[lt->tri[0]];
const int v2 = corner_verts[lt->tri[1]];
const int v3 = corner_verts[lt->tri[2]];
normal_tri_v3(values, positions[v1], positions[v2], positions[v3]);
}
@ -774,10 +799,10 @@ static float rna_MeshLoopTriangle_area_get(PointerRNA *ptr)
Mesh *me = rna_mesh(ptr);
MLoopTri *lt = (MLoopTri *)ptr->data;
const float(*positions)[3] = BKE_mesh_positions(me);
const MLoop *loops = BKE_mesh_loops(me);
uint v1 = loops[lt->tri[0]].v;
uint v2 = loops[lt->tri[1]].v;
uint v3 = loops[lt->tri[2]].v;
const int *corner_verts = BKE_mesh_corner_verts(me);
const int v1 = corner_verts[lt->tri[0]];
const int v2 = corner_verts[lt->tri[1]];
const int v3 = corner_verts[lt->tri[2]];
return area_tri_v3(positions[v1], positions[v2], positions[v3]);
}
@ -1409,27 +1434,16 @@ static int rna_MeshPoly_vertices_get_length(const PointerRNA *ptr,
static void rna_MeshPoly_vertices_get(PointerRNA *ptr, int *values)
{
Mesh *me = rna_mesh(ptr);
MPoly *mp = (MPoly *)ptr->data;
const MLoop *loops = BKE_mesh_loops(me);
const MLoop *ml = &loops[mp->loopstart];
uint i;
for (i = mp->totloop; i > 0; i--, values++, ml++) {
*values = ml->v;
}
const Mesh *me = rna_mesh(ptr);
const MPoly *mp = (const MPoly *)ptr->data;
memcpy(values, BKE_mesh_corner_verts(me) + mp->loopstart, sizeof(int) * mp->totloop);
}
static void rna_MeshPoly_vertices_set(PointerRNA *ptr, const int *values)
{
Mesh *me = rna_mesh(ptr);
const MPoly *mp = (const MPoly *)ptr->data;
MLoop *loops = BKE_mesh_loops_for_write(me);
MLoop *ml = &loops[mp->loopstart];
uint i;
for (i = mp->totloop; i > 0; i--, values++, ml++) {
ml->v = *values;
}
memcpy(BKE_mesh_corner_verts_for_write(me) + mp->loopstart, values, sizeof(int) * mp->totloop);
}
/* disabling, some importers don't know the total material count when assigning materials */
@ -1722,7 +1736,7 @@ static void rna_Mesh_loops_begin(CollectionPropertyIterator *iter, PointerRNA *p
{
Mesh *mesh = rna_mesh(ptr);
rna_iterator_array_begin(
iter, BKE_mesh_loops_for_write(mesh), sizeof(MLoop), mesh->totloop, false, NULL);
iter, BKE_mesh_corner_verts_for_write(mesh), sizeof(int), mesh->totloop, false, NULL);
}
static int rna_Mesh_loops_length(PointerRNA *ptr)
{
@ -1737,7 +1751,7 @@ int rna_Mesh_loops_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
}
r_ptr->owner_id = &mesh->id;
r_ptr->type = &RNA_MeshLoop;
r_ptr->data = &BKE_mesh_loops_for_write(mesh)[index];
r_ptr->data = &BKE_mesh_corner_verts_for_write(mesh)[index];
return true;
}
@ -2450,17 +2464,18 @@ static void rna_def_mloop(BlenderRNA *brna)
PropertyRNA *prop;
srna = RNA_def_struct(brna, "MeshLoop", NULL);
RNA_def_struct_sdna(srna, "MLoop");
RNA_def_struct_ui_text(srna, "Mesh Loop", "Loop in a Mesh data-block");
RNA_def_struct_path_func(srna, "rna_MeshLoop_path");
RNA_def_struct_ui_icon(srna, ICON_EDGESEL);
prop = RNA_def_property(srna, "vertex_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "v");
RNA_def_property_int_funcs(
prop, "rna_MeshLoop_vertex_index_get", "rna_MeshLoop_vertex_index_set", false);
RNA_def_property_ui_text(prop, "Vertex", "Vertex index");
prop = RNA_def_property(srna, "edge_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "e");
RNA_def_property_int_funcs(
prop, "rna_MeshLoop_edge_index_get", "rna_MeshLoop_edge_index_set", false);
RNA_def_property_ui_text(prop, "Edge", "Edge index");
prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);

View File

@ -95,7 +95,7 @@ static void rna_Mesh_calc_smooth_groups(
mesh->totedge,
BKE_mesh_polys(mesh),
mesh->totpoly,
BKE_mesh_loops(mesh),
BKE_mesh_corner_edges(mesh),
mesh->totloop,
r_group_total,
use_bitflags);
@ -166,8 +166,11 @@ static void rna_Mesh_transform(Mesh *mesh, float mat[16], bool shape_keys)
static void rna_Mesh_flip_normals(Mesh *mesh)
{
BKE_mesh_polys_flip(
BKE_mesh_polys(mesh), BKE_mesh_loops_for_write(mesh), &mesh->ldata, mesh->totpoly);
BKE_mesh_polys_flip(BKE_mesh_polys(mesh),
BKE_mesh_corner_verts_for_write(mesh),
BKE_mesh_corner_edges_for_write(mesh),
&mesh->ldata,
mesh->totpoly);
BKE_mesh_tessface_clear(mesh);
BKE_mesh_runtime_clear_geometry(mesh);

View File

@ -276,12 +276,12 @@ static void mesh_merge_transform(Mesh *result,
int *index_orig;
int i;
MEdge *me;
MLoop *ml;
MPoly *mp;
float(*result_positions)[3] = BKE_mesh_positions_for_write(result);
MEdge *result_edges = BKE_mesh_edges_for_write(result);
MPoly *result_polys = BKE_mesh_polys_for_write(result);
MLoop *result_loops = BKE_mesh_loops_for_write(result);
int *result_corner_verts = BKE_mesh_corner_verts_for_write(result);
int *result_corner_edges = BKE_mesh_corner_edges_for_write(result);
CustomData_copy_data(&cap_mesh->vdata, &result->vdata, 0, cap_verts_index, cap_nverts);
CustomData_copy_data(&cap_mesh->edata, &result->edata, 0, cap_edges_index, cap_nedges);
@ -321,10 +321,9 @@ static void mesh_merge_transform(Mesh *result,
}
/* adjust cap loop vertex and edge indices */
ml = result_loops + cap_loops_index;
for (i = 0; i < cap_nloops; i++, ml++) {
ml->v += cap_verts_index;
ml->e += cap_edges_index;
for (i = 0; i < cap_nloops; i++) {
result_corner_verts[cap_loops_index + i] += cap_verts_index;
result_corner_edges[cap_loops_index + i] += cap_edges_index;
}
/* Set #CD_ORIGINDEX. */
@ -354,7 +353,6 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
const Mesh *mesh)
{
MEdge *me;
MLoop *ml;
MPoly *mp;
int i, j, c, count;
float length = amd->length;
@ -427,7 +425,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
unit_m4(offset);
const MEdge *src_edges = BKE_mesh_edges(mesh);
const MPoly *src_polys = BKE_mesh_polys(mesh);
const MLoop *src_loops = BKE_mesh_loops(mesh);
const int *src_corner_verts = BKE_mesh_corner_verts(mesh);
const int *src_corner_edges = BKE_mesh_corner_edges(mesh);
if (amd->offset_type & MOD_ARR_OFF_CONST) {
add_v3_v3(offset[3], amd->offset);
@ -536,7 +535,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
float(*result_positions)[3] = BKE_mesh_positions_for_write(result);
MEdge *result_edges = BKE_mesh_edges_for_write(result);
MPoly *result_polys = BKE_mesh_polys_for_write(result);
MLoop *result_loops = BKE_mesh_loops_for_write(result);
int *result_corner_verts = BKE_mesh_corner_verts_for_write(result);
int *result_corner_edges = BKE_mesh_corner_edges_for_write(result);
if (use_merge) {
/* Will need full_doubles_map for handling merge */
@ -556,7 +556,8 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
memcpy(result_edges, src_edges, sizeof(MEdge) * mesh->totedge);
}
if (!CustomData_has_layer(&mesh->pdata, CD_MPOLY)) {
memcpy(result_loops, src_loops, sizeof(MLoop) * mesh->totloop);
memcpy(result_corner_verts, src_corner_verts, sizeof(int) * mesh->totloop);
memcpy(result_corner_edges, src_corner_edges, sizeof(int) * mesh->totloop);
memcpy(result_polys, src_polys, sizeof(MPoly) * mesh->totpoly);
}
@ -611,10 +612,10 @@ static Mesh *arrayModifier_doArray(ArrayModifierData *amd,
}
/* adjust loop vertex and edge indices */
ml = result_loops + c * chunk_nloops;
for (i = 0; i < chunk_nloops; i++, ml++) {
ml->v += c * chunk_nverts;
ml->e += c * chunk_nedges;
const int chunk_corner_start = c * chunk_nloops;
for (i = 0; i < chunk_nloops; i++) {
result_corner_verts[chunk_corner_start] += c * chunk_nverts;
result_corner_edges[chunk_corner_start] += c * chunk_nedges;
}
/* Handle merge between chunk n and n-1 */

View File

@ -62,8 +62,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
int *vertMap, *edgeMap, *faceMap;
float frac;
MPoly *mpoly_dst;
MLoop *ml_dst;
const MLoop *ml_src;
GHashIterator gh_iter;
/* maps vert indices in old mesh to indices in new mesh */
GHash *vertHash = BLI_ghash_int_new("build ve apply gh");
@ -77,7 +75,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
const int poly_src_num = mesh->totpoly;
const MEdge *medge_src = BKE_mesh_edges(mesh);
const MPoly *mpoly_src = BKE_mesh_polys(mesh);
const MLoop *mloop_src = BKE_mesh_loops(mesh);
const int *corner_verts_src = BKE_mesh_corner_verts(mesh);
const int *corner_edges_src = BKE_mesh_corner_edges(mesh);
vertMap = MEM_malloc_arrayN(vert_src_num, sizeof(*vertMap), "build modifier vertMap");
edgeMap = MEM_malloc_arrayN(edge_src_num, sizeof(*edgeMap), "build modifier edgeMap");
@ -100,7 +99,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
/* if there's at least one face, build based on faces */
if (faces_dst_num) {
const MPoly *mpoly, *mp;
const MLoop *ml, *mloop;
uintptr_t hash_num, hash_num_alt;
if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) {
@ -111,15 +109,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
* mapped to the new indices
*/
mpoly = mpoly_src;
mloop = mloop_src;
hash_num = 0;
for (i = 0; i < faces_dst_num; i++) {
mp = mpoly + faceMap[i];
ml = mloop + mp->loopstart;
for (j = 0; j < mp->totloop; j++, ml++) {
for (j = 0; j < mp->totloop; j++) {
const int vert_i = corner_verts_src[mp->loopstart + j];
void **val_p;
if (!BLI_ghash_ensure_p(vertHash, POINTER_FROM_INT(ml->v), &val_p)) {
if (!BLI_ghash_ensure_p(vertHash, POINTER_FROM_INT(vert_i), &val_p)) {
*val_p = (void *)hash_num;
hash_num++;
}
@ -203,7 +199,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
mesh, BLI_ghash_len(vertHash), BLI_ghash_len(edgeHash), 0, loops_dst_num, faces_dst_num);
MEdge *result_edges = BKE_mesh_edges_for_write(result);
MPoly *result_polys = BKE_mesh_polys_for_write(result);
MLoop *result_loops = BKE_mesh_loops_for_write(result);
int *result_corner_verts = BKE_mesh_corner_verts_for_write(result);
int *result_corner_edges = BKE_mesh_corner_edges_for_write(result);
/* copy the vertices across */
GHASH_ITER (gh_iter, vertHash) {
@ -229,7 +226,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
}
mpoly_dst = result_polys;
ml_dst = result_loops;
/* copy the faces across, remapping indices */
k = 0;
@ -246,10 +242,13 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, struct
CustomData_copy_data(
&mesh->ldata, &result->ldata, source->loopstart, dest->loopstart, dest->totloop);
ml_src = mloop_src + source->loopstart;
for (j = 0; j < source->totloop; j++, k++, ml_src++, ml_dst++) {
ml_dst->v = POINTER_AS_INT(BLI_ghash_lookup(vertHash, POINTER_FROM_INT(ml_src->v)));
ml_dst->e = POINTER_AS_INT(BLI_ghash_lookup(edgeHash2, POINTER_FROM_INT(ml_src->e)));
for (j = 0; j < source->totloop; j++, k++) {
const int vert_src = corner_verts_src[source->loopstart + j];
const int edge_src = corner_edges_src[source->loopstart + j];
result_corner_verts[dest->loopstart + j] = POINTER_AS_INT(
BLI_ghash_lookup(vertHash, POINTER_FROM_INT(vert_src)));
result_corner_edges[dest->loopstart + j] = POINTER_AS_INT(
BLI_ghash_lookup(edgeHash2, POINTER_FROM_INT(edge_src)));
}
}

View File

@ -159,11 +159,11 @@ static void deformVerts(ModifierData *md,
collmd->mvert_num = mvert_num;
{
const MLoop *mloop = BKE_mesh_loops(mesh_src);
const MLoopTri *looptri = BKE_mesh_runtime_looptri_ensure(mesh_src);
collmd->tri_num = BKE_mesh_runtime_looptri_len(mesh_src);
MVertTri *tri = MEM_mallocN(sizeof(*tri) * collmd->tri_num, __func__);
BKE_mesh_runtime_verttri_from_looptri(tri, mloop, looptri, collmd->tri_num);
BKE_mesh_runtime_verttri_from_looptri(
tri, BKE_mesh_corner_verts(mesh_src), looptri, collmd->tri_num);
collmd->tri = tri;
}

View File

@ -129,7 +129,7 @@ static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights)
{
const MEdge *medge = BKE_mesh_edges(mesh);
const MPoly *mpoly = BKE_mesh_polys(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
const int *corner_edges = BKE_mesh_corner_edges(mesh);
const uint mpoly_num = (uint)mesh->totpoly;
const uint medge_num = (uint)mesh->totedge;
@ -142,7 +142,7 @@ static void mesh_get_boundaries(Mesh *mesh, float *smooth_weights)
const int totloop = p->totloop;
int j;
for (j = 0; j < totloop; j++) {
uint8_t *e_value = &boundaries[mloop[p->loopstart + j].e];
uint8_t *e_value = &boundaries[corner_edges[p->loopstart + j]];
*e_value |= (uint8_t)((*e_value) + 1);
}
}
@ -436,7 +436,7 @@ static void calc_tangent_spaces(const Mesh *mesh,
const uint mpoly_num = (uint)mesh->totpoly;
const uint mvert_num = (uint)mesh->totvert;
const MPoly *mpoly = BKE_mesh_polys(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
const int *corner_verts = BKE_mesh_corner_verts(mesh);
uint i;
if (r_tangent_weights_per_vertex != NULL) {
@ -445,40 +445,39 @@ static void calc_tangent_spaces(const Mesh *mesh,
for (i = 0; i < mpoly_num; i++) {
const MPoly *mp = &mpoly[i];
const MLoop *l_next = &mloop[mp->loopstart];
const MLoop *l_term = l_next + mp->totloop;
const MLoop *l_prev = l_term - 2;
const MLoop *l_curr = l_term - 1;
int next_corner = mp->loopstart;
int term_corner = next_corner + mp->totloop;
int prev_corner = term_corner - 2;
int curr_corner = term_corner - 1;
/* loop directions */
float v_dir_prev[3], v_dir_next[3];
/* needed entering the loop */
sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->v], vertexCos[l_curr->v]);
sub_v3_v3v3(v_dir_prev, vertexCos[ corner_verts[prev_corner] ], vertexCos[corner_verts[curr_corner]]);
normalize_v3(v_dir_prev);
for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) {
uint l_index = (uint)(l_curr - mloop);
float(*ts)[3] = r_tangent_spaces[l_index];
for (; next_corner != term_corner; prev_corner = curr_corner, curr_corner = next_corner, next_corner++) {
float(*ts)[3] = r_tangent_spaces[curr_corner];
/* re-use the previous value */
#if 0
sub_v3_v3v3(v_dir_prev, vertexCos[l_prev->v], vertexCos[l_curr->v]);
sub_v3_v3v3(v_dir_prev, vertexCos[corner_verts[prev_corner]], vertexCos[corner_verts[curr_corner]]);
normalize_v3(v_dir_prev);
#endif
sub_v3_v3v3(v_dir_next, vertexCos[l_curr->v], vertexCos[l_next->v]);
sub_v3_v3v3(v_dir_next, vertexCos[corner_verts[curr_corner]], vertexCos[corner_verts[next_corner]]);
normalize_v3(v_dir_next);
if (calc_tangent_loop(v_dir_prev, v_dir_next, ts)) {
if (r_tangent_weights != NULL) {
const float weight = fabsf(acosf(dot_v3v3(v_dir_next, v_dir_prev)));
r_tangent_weights[l_index] = weight;
r_tangent_weights_per_vertex[l_curr->v] += weight;
r_tangent_weights[curr_corner] = weight;
r_tangent_weights_per_vertex[corner_verts[curr_corner]] += weight;
}
}
else {
if (r_tangent_weights != NULL) {
r_tangent_weights[l_index] = 0;
r_tangent_weights[curr_corner] = 0;
}
}
@ -515,7 +514,7 @@ static void calc_deltas(CorrectiveSmoothModifierData *csmd,
const float (*rest_coords)[3],
uint verts_num)
{
const MLoop *mloop = BKE_mesh_loops(mesh);
const int *corner_verts = BKE_mesh_corner_verts(mesh);
const uint loops_num = (uint)mesh->totloop;
float(*smooth_vertex_coords)[3] = MEM_dupallocN(rest_coords);
@ -542,7 +541,7 @@ static void calc_deltas(CorrectiveSmoothModifierData *csmd,
copy_vn_fl(&csmd->delta_cache.deltas[0][0], (int)loops_num * 3, 0.0f);
for (l_index = 0; l_index < loops_num; l_index++) {
const int v_index = (int)mloop[l_index].v;
const int v_index = corner_verts[l_index];
float delta[3];
sub_v3_v3v3(delta, rest_coords[v_index], smooth_vertex_coords[v_index]);
@ -573,7 +572,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
((csmd->rest_source == MOD_CORRECTIVESMOOTH_RESTSOURCE_ORCO) &&
(((ID *)ob->data)->recalc & ID_RECALC_ALL));
const MLoop *mloop = BKE_mesh_loops(mesh);
const int *corner_verts = BKE_mesh_corner_verts(mesh);
const uint loops_num = (uint)mesh->totloop;
bool use_only_smooth = (csmd->flag & MOD_CORRECTIVESMOOTH_ONLY_SMOOTH) != 0;
@ -702,7 +701,7 @@ static void correctivesmooth_modifier_do(ModifierData *md,
mesh, vertexCos, tangent_spaces, tangent_weights, tangent_weights_per_vertex);
for (l_index = 0; l_index < loops_num; l_index++) {
const uint v_index = mloop[l_index].v;
const int v_index = corner_verts[l_index];
const float weight = tangent_weights[l_index] / tangent_weights_per_vertex[v_index];
if (UNLIKELY(!(weight > 0.0f))) {
/* Catches zero & divide by zero. */

View File

@ -312,8 +312,11 @@ static void displaceModifier_do(DisplaceModifierData *dmd,
float(*clnors)[3] = static_cast<float(*)[3]>(CustomData_get_layer(ldata, CD_NORMAL));
vert_clnors = static_cast<float(*)[3]>(
MEM_malloc_arrayN(verts_num, sizeof(*vert_clnors), __func__));
BKE_mesh_normals_loop_to_vertex(
verts_num, BKE_mesh_loops(mesh), mesh->totloop, (const float(*)[3])clnors, vert_clnors);
BKE_mesh_normals_loop_to_vertex(verts_num,
BKE_mesh_corner_verts(mesh),
mesh->totloop,
(const float(*)[3])clnors,
vert_clnors);
}
else {
direction = MOD_DISP_DIR_NOR;

View File

@ -56,7 +56,7 @@ struct BLaplacianSystem {
/* Pointers to data. */
float (*vertexCos)[3];
const MPoly *mpoly;
const MLoop *mloop;
const int *corner_verts;
const MEdge *medges;
LinearSolver *context;
@ -70,7 +70,7 @@ static float compute_volume(const float center[3],
float (*vertexCos)[3],
const MPoly *mpoly,
int polys_num,
const MLoop *mloop);
const int *corner_verts);
static LaplacianSystem *init_laplacian_system(int a_numEdges,
int a_numPolys,
int a_numLoops,
@ -99,7 +99,7 @@ static void delete_laplacian_system(LaplacianSystem *sys)
}
sys->vertexCos = NULL;
sys->mpoly = NULL;
sys->mloop = NULL;
sys->corner_verts = NULL;
sys->medges = NULL;
MEM_freeN(sys);
}
@ -144,7 +144,7 @@ static float compute_volume(const float center[3],
float (*vertexCos)[3],
const MPoly *mpoly,
int polys_num,
const MLoop *mloop)
const int *corner_verts)
{
int i;
float vol = 0.0f;
@ -343,7 +343,7 @@ static void validate_solution(LaplacianSystem *sys, short flag, float lambda, fl
if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) {
vini = compute_volume(
sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->polys_num, sys->mloop);
sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->polys_num, sys->corner_verts);
}
for (i = 0; i < sys->verts_num; i++) {
if (sys->zerola[i] == false) {
@ -365,7 +365,7 @@ static void validate_solution(LaplacianSystem *sys, short flag, float lambda, fl
}
if (flag & MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME) {
vend = compute_volume(
sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->polys_num, sys->mloop);
sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->polys_num, sys->corner_verts);
volume_preservation(sys, vini, vend, flag);
}
}
@ -387,7 +387,7 @@ static void laplaciansmoothModifier_do(
}
sys->mpoly = BKE_mesh_polys(mesh);
sys->mloop = BKE_mesh_loops(mesh);
sys->corner_verts = BKE_mesh_corner_verts(mesh);
sys->medges = BKE_mesh_edges(mesh);
sys->vertexCos = vertexCos;
sys->min_area = 0.00001f;

View File

@ -231,7 +231,7 @@ static void computed_masked_polys(const Mesh *mesh,
{
BLI_assert(mesh->totvert == vertex_mask.size());
const Span<MPoly> polys = mesh->polys();
const Span<MLoop> loops = mesh->loops();
const Span<int> corner_verts = mesh->corner_verts();
r_masked_poly_indices.reserve(mesh->totpoly);
r_loop_starts.reserve(mesh->totpoly);
@ -241,9 +241,8 @@ static void computed_masked_polys(const Mesh *mesh,
const MPoly &poly_src = polys[i];
bool all_verts_in_mask = true;
Span<MLoop> loops_src = loops.slice(poly_src.loopstart, poly_src.totloop);
for (const MLoop &loop : loops_src) {
if (!vertex_mask[loop.v]) {
for (const int vert_i : corner_verts.slice(poly_src.loopstart, poly_src.totloop)) {
if (!vertex_mask[vert_i]) {
all_verts_in_mask = false;
break;
}
@ -277,7 +276,7 @@ static void compute_interpolated_polys(const Mesh *mesh,
r_masked_poly_indices.reserve(r_masked_poly_indices.size() + verts_add_num);
r_loop_starts.reserve(r_loop_starts.size() + verts_add_num);
const Span<MPoly> polys = mesh->polys();
const Span<MLoop> loops = mesh->loops();
const Span<int> corner_verts = mesh->corner_verts();
uint edges_add_num = 0;
uint polys_add_num = 0;
@ -288,10 +287,10 @@ static void compute_interpolated_polys(const Mesh *mesh,
int in_count = 0;
int start = -1;
int dst_totloop = -1;
const Span<MLoop> loops_src = loops.slice(poly_src.loopstart, poly_src.totloop);
for (const int j : loops_src.index_range()) {
const MLoop &loop = loops_src[j];
if (vertex_mask[loop.v]) {
const Span<int> poly_verts_src = corner_verts.slice(poly_src.loopstart, poly_src.totloop);
for (const int j : poly_verts_src.index_range()) {
const int vert_i = poly_verts_src[j];
if (vertex_mask[vert_i]) {
in_count++;
}
else if (start == -1) {
@ -300,11 +299,11 @@ static void compute_interpolated_polys(const Mesh *mesh,
}
if (0 < in_count && in_count < poly_src.totloop) {
/* Ring search starting at a vertex which is not included in the mask. */
const MLoop *last_loop = &loops_src[start];
bool v_loop_in_mask_last = vertex_mask[last_loop->v];
for (const int j : loops_src.index_range()) {
const MLoop &loop = loops_src[(start + 1 + j) % poly_src.totloop];
const bool v_loop_in_mask = vertex_mask[loop.v];
const int *last_corner_vert = &corner_verts[start];
bool v_loop_in_mask_last = vertex_mask[*last_corner_vert];
for (const int j : poly_verts_src.index_range()) {
const int &corner_vert = corner_verts[(start + 1 + j) % poly_src.totloop];
const bool v_loop_in_mask = vertex_mask[corner_vert];
if (v_loop_in_mask && !v_loop_in_mask_last) {
dst_totloop = 3;
}
@ -321,7 +320,7 @@ static void compute_interpolated_polys(const Mesh *mesh,
BLI_assert(dst_totloop > 2);
dst_totloop++;
}
last_loop = &loop;
last_corner_vert = &corner_vert;
v_loop_in_mask_last = v_loop_in_mask;
}
}
@ -453,9 +452,11 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
int polys_masked_num)
{
const Span<MPoly> src_polys = src_mesh.polys();
const Span<MLoop> src_loops = src_mesh.loops();
MutableSpan<MPoly> dst_polys = dst_mesh.polys_for_write();
MutableSpan<MLoop> dst_loops = dst_mesh.loops_for_write();
const Span<int> src_corner_verts = src_mesh.corner_verts();
const Span<int> src_corner_edges = src_mesh.corner_edges();
MutableSpan<int> dst_corner_verts = dst_mesh.corner_verts_for_write();
MutableSpan<int> dst_corner_edges = dst_mesh.corner_edges_for_write();
for (const int i_dst : IndexRange(polys_masked_num)) {
const int i_src = masked_poly_indices[i_dst];
@ -468,14 +469,11 @@ static void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
CustomData_copy_data(&src_mesh.pdata, &dst_mesh.pdata, i_src, i_dst, 1);
CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src, i_ml_dst, mp_src.totloop);
const MLoop *ml_src = src_loops.data() + i_ml_src;
MLoop *ml_dst = dst_loops.data() + i_ml_dst;
mp_dst = mp_src;
mp_dst.loopstart = i_ml_dst;
for (int i : IndexRange(mp_src.totloop)) {
ml_dst[i].v = vertex_map[ml_src[i].v];
ml_dst[i].e = edge_map[ml_src[i].e];
for (const int i : IndexRange(mp_dst.totloop)) {
dst_corner_verts[i_ml_dst + i] = src_corner_verts[vertex_map[i_ml_src + i]];
dst_corner_edges[i_ml_dst + i] = src_corner_edges[edge_map[i_ml_src + i]];
}
}
}
@ -494,10 +492,12 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh,
int edges_add_num)
{
const Span<MPoly> src_polys = src_mesh.polys();
const Span<MLoop> src_loops = src_mesh.loops();
MutableSpan<MEdge> dst_edges = dst_mesh.edges_for_write();
MutableSpan<MPoly> dst_polys = dst_mesh.polys_for_write();
MutableSpan<MLoop> dst_loops = dst_mesh.loops_for_write();
MutableSpan<MEdge> dst_edges = dst_mesh.edges_for_write();
const Span<int> src_corner_verts = src_mesh.corner_verts();
const Span<int> src_corner_edges = src_mesh.corner_edges();
MutableSpan<int> dst_corner_verts = dst_mesh.corner_verts_for_write();
MutableSpan<int> dst_corner_edges = dst_mesh.corner_edges_for_write();
int edge_index = dst_mesh.totedge - edges_add_num;
int sub_poly_index = 0;
@ -530,9 +530,9 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh,
/* Ring search starting at a vertex which is not included in the mask. */
int start = -sub_poly_index - 1;
bool skip = false;
Span<MLoop> loops_src(&src_loops[i_ml_src], mp_src.totloop);
for (const int j : loops_src.index_range()) {
if (!vertex_mask[loops_src[j].v]) {
Span<int> corner_verts_src(&src_corner_verts[i_ml_src], mp_src.totloop);
for (const int j : corner_verts_src.index_range()) {
if (!vertex_mask[corner_verts_src[j]]) {
if (start == -1) {
start = j;
break;
@ -550,50 +550,52 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh,
BLI_assert(start >= 0);
BLI_assert(edge_index < dst_mesh.totedge);
const MLoop *last_loop = &loops_src[start];
bool v_loop_in_mask_last = vertex_mask[last_loop->v];
int last_corner_i = start;
bool v_loop_in_mask_last = vertex_mask[src_corner_verts[last_corner_i]];
int last_index = start;
for (const int j : loops_src.index_range()) {
for (const int j : corner_verts_src.index_range()) {
const int index = (start + 1 + j) % mp_src.totloop;
const MLoop &loop = loops_src[index];
const bool v_loop_in_mask = vertex_mask[loop.v];
const bool v_loop_in_mask = vertex_mask[src_corner_verts[index]];
if (v_loop_in_mask && !v_loop_in_mask_last) {
/* Start new cut. */
float fac = get_interp_factor_from_vgroup(
dvert, defgrp_index, threshold, last_loop->v, loop.v);
float fac = get_interp_factor_from_vgroup(dvert,
defgrp_index,
threshold,
src_corner_verts[last_corner_i],
src_corner_verts[index]);
float weights[2] = {1.0f - fac, fac};
int indices[2] = {i_ml_src + last_index, i_ml_src + index};
CustomData_interp(
&src_mesh.ldata, &dst_mesh.ldata, indices, weights, nullptr, 2, i_ml_dst);
MLoop &cut_dst_loop = dst_loops[i_ml_dst];
cut_dst_loop.e = edge_map[last_loop->e];
cut_dst_loop.v = dst_edges[cut_dst_loop.e].v1;
dst_corner_edges[i_ml_dst] = edge_map[src_corner_edges[last_corner_i]];
dst_corner_verts[i_ml_dst] = dst_edges[dst_corner_edges[i_ml_dst]].v1;
i_ml_dst++;
CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src + index, i_ml_dst, 1);
MLoop &next_dst_loop = dst_loops[i_ml_dst];
next_dst_loop.v = vertex_map[loop.v];
next_dst_loop.e = edge_map[loop.e];
dst_corner_verts[i_ml_dst] = vertex_map[src_corner_verts[index]];
dst_corner_edges[i_ml_dst] = edge_map[src_corner_edges[index]];
i_ml_dst++;
}
else if (!v_loop_in_mask && v_loop_in_mask_last) {
BLI_assert(i_ml_dst != mp_dst.loopstart);
/* End active cut. */
float fac = get_interp_factor_from_vgroup(
dvert, defgrp_index, threshold, last_loop->v, loop.v);
float fac = get_interp_factor_from_vgroup(dvert,
defgrp_index,
threshold,
src_corner_verts[last_corner_i],
src_corner_verts[index]);
float weights[2] = {1.0f - fac, fac};
int indices[2] = {i_ml_src + last_index, i_ml_src + index};
CustomData_interp(
&src_mesh.ldata, &dst_mesh.ldata, indices, weights, nullptr, 2, i_ml_dst);
MLoop &cut_dst_loop = dst_loops[i_ml_dst];
cut_dst_loop.e = edge_index;
cut_dst_loop.v = dst_edges[edge_map[last_loop->e]].v1;
dst_corner_edges[i_ml_dst] = edge_index;
dst_corner_verts[i_ml_dst] = dst_edges[edge_map[src_corner_edges[last_corner_i]]].v1;
i_ml_dst++;
/* Create closing edge. */
MEdge &cut_edge = dst_edges[edge_index];
cut_edge.v1 = dst_loops[mp_dst.loopstart].v;
cut_edge.v2 = cut_dst_loop.v;
cut_edge.v1 = dst_corner_verts[mp_dst.loopstart];
cut_edge.v2 = dst_corner_verts[i_ml_dst];
BLI_assert(cut_edge.v1 != cut_edge.v2);
cut_edge.flag = ME_EDGEDRAW;
edge_index++;
@ -605,12 +607,11 @@ static void add_interpolated_polys_to_new_mesh(const Mesh &src_mesh,
BLI_assert(i_ml_dst != mp_dst.loopstart);
/* Extend active poly. */
CustomData_copy_data(&src_mesh.ldata, &dst_mesh.ldata, i_ml_src + index, i_ml_dst, 1);
MLoop &dst_loop = dst_loops[i_ml_dst];
dst_loop.v = vertex_map[loop.v];
dst_loop.e = edge_map[loop.e];
dst_corner_verts[i_ml_dst] = vertex_map[src_corner_verts[index]];
dst_corner_edges[i_ml_dst] = edge_map[src_corner_edges[index]];
i_ml_dst++;
}
last_loop = &loop;
last_corner_i = index;
last_index = index;
v_loop_in_mask_last = v_loop_in_mask;
}

View File

@ -182,7 +182,7 @@ static void meshcache_do(MeshCacheModifierData *mcmd,
BKE_mesh_calc_relative_deform(
BKE_mesh_polys(me),
me->totpoly,
BKE_mesh_loops(me),
BKE_mesh_corner_verts(me),
me->totvert,
(const float(*)[3])positions, /* From the original Mesh. */

View File

@ -64,7 +64,7 @@ static void init_dualcon_mesh(DualConInput *input, Mesh *mesh)
input->co_stride = sizeof(float[3]);
input->totco = mesh->totvert;
input->mloop = (void *)BKE_mesh_loops(mesh);
input->mloop = (void *)BKE_mesh_corner_verts(mesh);
input->loop_stride = sizeof(int);
input->looptri = (void *)BKE_mesh_runtime_looptri_ensure(mesh);

View File

@ -240,7 +240,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
uint edge_offset;
MPoly *mp_new;
MLoop *ml_new;
int *corner_verts_new;
int *corner_edges_new;
MEdge *med_new, *med_new_firstloop;
Object *ob_axis = ltmd->ob_axis;
@ -384,12 +385,14 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
const float(*positions_orig)[3] = BKE_mesh_positions(mesh);
const MEdge *medge_orig = BKE_mesh_edges(mesh);
const MPoly *mpoly_orig = BKE_mesh_polys(mesh);
const MLoop *mloop_orig = BKE_mesh_loops(mesh);
const int *corner_verts_orig = BKE_mesh_corner_verts(mesh);
const int *corner_edges_orig = BKE_mesh_corner_edges(mesh);
float(*positions_new)[3] = BKE_mesh_positions_for_write(result);
MEdge *medge_new = BKE_mesh_edges_for_write(result);
MPoly *mpoly_new = BKE_mesh_polys_for_write(result);
MLoop *mloop_new = BKE_mesh_loops_for_write(result);
int *corner_verts_orig = BKE_mesh_corner_verts_for_write(result);
int *corner_edges_orig = BKE_mesh_corner_edges_for_write(result);
if (!CustomData_has_layer(&result->pdata, CD_ORIGINDEX)) {
CustomData_add_layer(&result->pdata, CD_ORIGINDEX, CD_SET_DEFAULT, NULL, (int)maxPolys);
@ -449,15 +452,16 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
uint loopstart = (uint)mp_orig->loopstart;
uint loopend = loopstart + (uint)mp_orig->totloop;
const MLoop *ml_orig = &mloop_orig[loopstart];
uint k;
for (k = loopstart; k < loopend; k++, ml_orig++) {
edge_poly_map[ml_orig->e] = i;
vert_loop_map[ml_orig->v] = k;
for (k = loopstart; k < loopend; k++) {
const int vert_i = corner_verts_orig[loopstart + k];
const int edge_i = corner_edges_orig[loopstart + k];
edge_poly_map[edge_i] = i;
vert_loop_map[vert_i] = k;
/* also order edges based on faces */
if (medge_new[ml_orig->e].v1 != ml_orig->v) {
SWAP(uint, medge_new[ml_orig->e].v1, medge_new[ml_orig->e].v2);
if (medge_new[edge_i].v1 != vert_i) {
SWAP(uint, medge_new[edge_i].v1, medge_new[edge_i].v2);
}
}
}
@ -822,7 +826,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
mp_new = mpoly_new;
ml_new = mloop_new;
int dst_corner_i = 0;
med_new_firstloop = medge_new;
/* more of an offset in this case */
@ -884,23 +888,21 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Loop-Custom-Data */
if (has_mloop_orig) {
int l_index = (int)(ml_new - mloop_new);
CustomData_copy_data(
&mesh->ldata, &result->ldata, (int)mloop_index_orig[0], l_index + 0, 1);
&mesh->ldata, &result->ldata, (int)mloop_index_orig[0], dst_corner_i + 0, 1);
CustomData_copy_data(
&mesh->ldata, &result->ldata, (int)mloop_index_orig[1], l_index + 1, 1);
&mesh->ldata, &result->ldata, (int)mloop_index_orig[1], dst_corner_i + 1, 1);
CustomData_copy_data(
&mesh->ldata, &result->ldata, (int)mloop_index_orig[1], l_index + 2, 1);
&mesh->ldata, &result->ldata, (int)mloop_index_orig[1], dst_corner_i + 2, 1);
CustomData_copy_data(
&mesh->ldata, &result->ldata, (int)mloop_index_orig[0], l_index + 3, 1);
&mesh->ldata, &result->ldata, (int)mloop_index_orig[0], dst_corner_i + 3, 1);
if (mloopuv_layers_tot) {
uint uv_lay;
const float uv_u_offset_a = (float)(step)*uv_u_scale;
const float uv_u_offset_b = (float)(step + 1) * uv_u_scale;
for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index];
MLoopUV *mluv = &mloopuv_layers[uv_lay][dst_corner_i];
mluv[quad_ord[0]].uv[0] += uv_u_offset_a;
mluv[quad_ord[1]].uv[0] += uv_u_offset_a;
@ -911,13 +913,11 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
else {
if (mloopuv_layers_tot) {
int l_index = (int)(ml_new - mloop_new);
uint uv_lay;
const float uv_u_offset_a = (float)(step)*uv_u_scale;
const float uv_u_offset_b = (float)(step + 1) * uv_u_scale;
for (uv_lay = 0; uv_lay < mloopuv_layers_tot; uv_lay++) {
MLoopUV *mluv = &mloopuv_layers[uv_lay][l_index];
MLoopUV *mluv = &mloopuv_layers[uv_lay][dst_corner_i];
copy_v2_fl2(mluv[quad_ord[0]].uv, uv_u_offset_a, uv_v_offset_a);
copy_v2_fl2(mluv[quad_ord[1]].uv, uv_u_offset_a, uv_v_offset_b);
@ -930,16 +930,18 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Loop-Data */
if (!(close && step == step_last)) {
/* regular segments */
ml_new[quad_ord[0]].v = i1;
ml_new[quad_ord[1]].v = i2;
ml_new[quad_ord[2]].v = i2 + totvert;
ml_new[quad_ord[3]].v = i1 + totvert;
corner_verts_new[dst_corner_i + quad_ord[0]] = i1;
corner_verts_new[dst_corner_i + quad_ord[0]] = i1;
corner_verts_new[dst_corner_i + quad_ord[1]] = i2;
corner_verts_new[dst_corner_i + quad_ord[2]] = i2 + totvert;
corner_verts_new[dst_corner_i + quad_ord[3]] = i1 + totvert;
ml_new[quad_ord_ofs[0]].e = step == 0 ? i :
(edge_offset + step + (i * (step_tot - 1))) - 1;
ml_new[quad_ord_ofs[1]].e = totedge + i2;
ml_new[quad_ord_ofs[2]].e = edge_offset + step + (i * (step_tot - 1));
ml_new[quad_ord_ofs[3]].e = totedge + i1;
corner_edges_new[dst_corner_i + quad_ord_ofs[0]] =
step == 0 ? i : (edge_offset + step + (i * (step_tot - 1))) - 1;
corner_edges_new[dst_corner_i + quad_ord_ofs[1]] = totedge + i2;
corner_edges_new[dst_corner_i + quad_ord_ofs[2]] = edge_offset + step +
(i * (step_tot - 1));
corner_edges_new[dst_corner_i + quad_ord_ofs[3]] = totedge + i1;
/* new vertical edge */
if (step) { /* The first set is already done */
@ -953,19 +955,21 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
else {
/* last segment */
ml_new[quad_ord[0]].v = i1;
ml_new[quad_ord[1]].v = i2;
ml_new[quad_ord[2]].v = med_new_firstloop->v2;
ml_new[quad_ord[3]].v = med_new_firstloop->v1;
corner_verts_new[dst_corner_i + quad_ord[0]] = i1;
corner_verts_new[dst_corner_i + quad_ord[1]] = i2;
corner_verts_new[dst_corner_i + quad_ord[2]] = med_new_firstloop->v2;
corner_verts_new[dst_corner_i + quad_ord[3]] = med_new_firstloop->v1;
ml_new[quad_ord_ofs[0]].e = (edge_offset + step + (i * (step_tot - 1))) - 1;
ml_new[quad_ord_ofs[1]].e = totedge + i2;
ml_new[quad_ord_ofs[2]].e = i;
ml_new[quad_ord_ofs[3]].e = totedge + i1;
corner_edges_new[dst_corner_i + quad_ord_ofs[0]] = (edge_offset + step +
(i * (step_tot - 1))) -
1;
corner_edges_new[dst_corner_i + quad_ord_ofs[1]] = totedge + i2;
corner_edges_new[dst_corner_i + quad_ord_ofs[2]] = i;
corner_edges_new[dst_corner_i + quad_ord_ofs[3]] = totedge + i1;
}
mp_new++;
ml_new += 4;
dst_corner_i += 4;
mpoly_index++;
}

View File

@ -67,7 +67,7 @@ static void mesh_calc_hq_normal(Mesh *mesh,
const int edges_num = mesh->totedge;
const int polys_num = mesh->totpoly;
const MPoly *mpoly = BKE_mesh_polys(mesh);
const MLoop *mloop = BKE_mesh_loops(mesh);
const int *corner_edges = BKE_mesh_corner_edges(mesh);
const MEdge *medge = BKE_mesh_edges(mesh);
const MPoly *mp = mpoly;
@ -82,11 +82,11 @@ static void mesh_calc_hq_normal(Mesh *mesh,
for (i = 0; i < polys_num; i++, mp++) {
int j;
const MLoop *ml = mloop + mp->loopstart;
for (j = 0; j < mp->totloop; j++) {
const int edge_i = corner_edges[mp->loopstart + j];
for (j = 0; j < mp->totloop; j++, ml++) {
/* --- add edge ref to face --- */
edge_ref = &edge_ref_array[ml->e];
edge_ref = &edge_ref_array[edge_i];
if (!edgeref_is_init(edge_ref)) {
edge_ref->p1 = i;
edge_ref->p2 = -1;
@ -98,7 +98,7 @@ static void mesh_calc_hq_normal(Mesh *mesh,
/* 3+ faces using an edge, we can't handle this usefully */
edge_ref->p1 = edge_ref->p2 = -1;
#ifdef USE_NONMANIFOLD_WORKAROUND
BLI_BITMAP_ENABLE(edge_tmp_tag, ml->e);
BLI_BITMAP_ENABLE(edge_tmp_tag, edge_i);
#endif
}
/* --- done --- */
@ -218,7 +218,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
const float(*orig_positions)[3] = BKE_mesh_positions(mesh);
const MEdge *orig_medge = BKE_mesh_edges(mesh);
const MPoly *orig_mpoly = BKE_mesh_polys(mesh);
const MLoop *orig_mloop = BKE_mesh_loops(mesh);
const int *orig_corner_verts = BKE_mesh_corner_verts(mesh);
const int *orig_corner_edges = BKE_mesh_corner_edges(mesh);
if (need_poly_normals) {
/* calculate only face normals */

View File

@ -187,7 +187,7 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
const float(*orig_positions)[3] = BKE_mesh_positions(mesh);
const MEdge *orig_medge = BKE_mesh_edges(mesh);
const MPoly *orig_mpoly = BKE_mesh_polys(mesh);
const MLoop *orig_mloop = BKE_mesh_loops(mesh);
const MLoop *orig_mloop = BKE_mesh_corner_verts(mesh);
/* These might be null. */
const float *orig_vert_bweight = CustomData_get_layer(&mesh->vdata, CD_BWEIGHT);

View File

@ -304,8 +304,10 @@ static Array<Vector<int, 2>> mesh_calculate_polys_of_edge(const Mesh &mesh)
return polys_of_edge;
}
static void fill_quad_consistent_direction(Span<MLoop> other_poly_loops,
MutableSpan<MLoop> new_loops,
static void fill_quad_consistent_direction(const Span<int> other_poly_verts,
const Span<int> other_poly_edges,
MutableSpan<int> new_corner_verts,
MutableSpan<int> new_corner_edges,
const int vert_connected_to_poly_1,
const int vert_connected_to_poly_2,
const int vert_across_from_poly_1,
@ -317,31 +319,31 @@ static void fill_quad_consistent_direction(Span<MLoop> other_poly_loops,
{
/* Find the loop on the polygon connected to the new quad that uses the duplicate edge. */
bool start_with_connecting_edge = true;
for (const MLoop &loop : other_poly_loops) {
if (loop.e == edge_connected_to_poly) {
start_with_connecting_edge = loop.v == vert_connected_to_poly_1;
for (const int i : other_poly_verts.index_range()) {
if (other_poly_edges[i] == edge_connected_to_poly) {
start_with_connecting_edge = other_poly_verts[i] == vert_connected_to_poly_1;
break;
}
}
if (start_with_connecting_edge) {
new_loops[0].v = vert_connected_to_poly_1;
new_loops[0].e = connecting_edge_1;
new_loops[1].v = vert_across_from_poly_1;
new_loops[1].e = edge_across_from_poly;
new_loops[2].v = vert_across_from_poly_2;
new_loops[2].e = connecting_edge_2;
new_loops[3].v = vert_connected_to_poly_2;
new_loops[3].e = edge_connected_to_poly;
new_corner_verts[0] = vert_connected_to_poly_1;
new_corner_edges[0] = connecting_edge_1;
new_corner_verts[1] = vert_across_from_poly_1;
new_corner_edges[1] = edge_across_from_poly;
new_corner_verts[2] = vert_across_from_poly_2;
new_corner_edges[2] = connecting_edge_2;
new_corner_verts[3] = vert_connected_to_poly_2;
new_corner_edges[3] = edge_connected_to_poly;
}
else {
new_loops[0].v = vert_connected_to_poly_1;
new_loops[0].e = edge_connected_to_poly;
new_loops[1].v = vert_connected_to_poly_2;
new_loops[1].e = connecting_edge_2;
new_loops[2].v = vert_across_from_poly_2;
new_loops[2].e = edge_across_from_poly;
new_loops[3].v = vert_across_from_poly_1;
new_loops[3].e = connecting_edge_1;
new_corner_verts[0] = vert_connected_to_poly_1;
new_corner_edges[0] = edge_connected_to_poly;
new_corner_verts[1] = vert_connected_to_poly_2;
new_corner_edges[1] = connecting_edge_2;
new_corner_verts[2] = vert_across_from_poly_2;
new_corner_edges[2] = edge_across_from_poly;
new_corner_verts[3] = vert_across_from_poly_1;
new_corner_edges[3] = connecting_edge_1;
}
}
@ -422,8 +424,10 @@ static void extrude_mesh_edges(Mesh &mesh,
MutableSpan<MEdge> duplicate_edges = edges.slice(duplicate_edge_range);
MutableSpan<MPoly> polys = mesh.polys_for_write();
MutableSpan<MPoly> new_polys = polys.slice(new_poly_range);
MutableSpan<MLoop> loops = mesh.loops_for_write();
MutableSpan<MLoop> new_loops = loops.slice(new_loop_range);
MutableSpan<int> corner_verts = mesh.corner_verts_for_write();
MutableSpan<int> new_corner_verts = corner_verts.slice(new_loop_range);
MutableSpan<int> corner_edges = mesh.corner_edges_for_write();
MutableSpan<int> new_corner_edges = corner_edges.slice(new_loop_range);
for (const int i : connect_edges.index_range()) {
connect_edges[i] = new_edge(new_vert_indices[i], new_vert_range[i]);
@ -454,13 +458,17 @@ static void extrude_mesh_edges(Mesh &mesh,
/* When there was a single polygon connected to the new polygon, we can use the old one to keep
* the face direction consistent. When there is more than one connected edge, the new face
* direction is totally arbitrary and the only goal for the behavior is to be deterministic. */
Span<MLoop> connected_poly_loops = {};
Span<int> connected_poly_verts;
Span<int> connected_poly_edges;
if (connected_polys.size() == 1) {
const MPoly &connected_poly = polys[connected_polys.first()];
connected_poly_loops = loops.slice(connected_poly.loopstart, connected_poly.totloop);
connected_poly_verts = corner_verts.slice(connected_poly.loopstart, connected_poly.totloop);
connected_poly_edges = corner_edges.slice(connected_poly.loopstart, connected_poly.totloop);
}
fill_quad_consistent_direction(connected_poly_loops,
new_loops.slice(4 * i, 4),
fill_quad_consistent_direction(connected_poly_verts,
connected_poly_edges,
new_corner_verts.slice(4 * i, 4),
new_corner_edges.slice(4 * i, 4),
new_vert_indices[extrude_index_1],
new_vert_indices[extrude_index_2],
new_vert_1,
@ -551,13 +559,12 @@ static void extrude_mesh_edges(Mesh &mesh,
* polygons that share an edge with the extruded edge. */
for (const int i_connected_poly : connected_polys.index_range()) {
const MPoly &connected_poly = polys[connected_polys[i_connected_poly]];
for (const int i_loop :
IndexRange(connected_poly.loopstart, connected_poly.totloop)) {
const MLoop &loop = loops[i_loop];
if (loop.v == orig_vert_1) {
for (const int vert_i :
corner_verts.slice(connected_poly.loopstart, connected_poly.totloop)) {
if (vert_i == orig_vert_1) {
mixer.mix_in(0, data[i_loop]);
}
if (loop.v == orig_vert_2) {
if (vert_i == orig_vert_2) {
mixer.mix_in(1, data[i_loop]);
}
}
@ -640,7 +647,7 @@ static void extrude_mesh_face_regions(Mesh &mesh,
const int orig_vert_size = mesh.totvert;
Span<MEdge> orig_edges = mesh.edges();
Span<MPoly> orig_polys = mesh.polys();
Span<MLoop> orig_loops = mesh.loops();
Span<int> orig_corner_verts = mesh.corner_verts();
bke::MeshFieldContext poly_context{mesh, ATTR_DOMAIN_FACE};
FieldEvaluator poly_evaluator{poly_context, mesh.totpoly};
@ -668,8 +675,8 @@ static void extrude_mesh_face_regions(Mesh &mesh,
for (const int i_poly : poly_selection) {
const MPoly &poly = orig_polys[i_poly];
const float3 offset = poly_offsets[i_poly];
for (const MLoop &loop : orig_loops.slice(poly.loopstart, poly.totloop)) {
mixer.mix_in(loop.v, offset);
for (const int vert_i : orig_corner_verts.slice(poly.loopstart, poly.totloop)) {
mixer.mix_in(vert_i, offset);
}
}
mixer.finalize();
@ -684,8 +691,8 @@ static void extrude_mesh_face_regions(Mesh &mesh,
all_selected_verts.reserve(orig_polys.size());
for (const int i_poly : poly_selection) {
const MPoly &poly = orig_polys[i_poly];
for (const MLoop &loop : orig_loops.slice(poly.loopstart, poly.totloop)) {
all_selected_verts.add(loop.v);
for (const int vert_i : orig_corner_verts.slice(poly.loopstart, poly.totloop)) {
all_selected_verts.add(vert_i);
}
}
@ -759,7 +766,7 @@ static void extrude_mesh_face_regions(Mesh &mesh,
/* Each edge selected for extrusion is extruded into a single face. */
const IndexRange side_poly_range{orig_polys.size(), boundary_edge_indices.size()};
/* The loops that form the new side faces. */
const IndexRange side_loop_range{orig_loops.size(), side_poly_range.size() * 4};
const IndexRange side_loop_range{orig_corner_verts.size(), side_poly_range.size() * 4};
expand_mesh(mesh,
new_vert_range.size(),
@ -773,8 +780,10 @@ static void extrude_mesh_face_regions(Mesh &mesh,
MutableSpan<MEdge> new_inner_edges = edges.slice(new_inner_edge_range);
MutableSpan<MPoly> polys = mesh.polys_for_write();
MutableSpan<MPoly> new_polys = polys.slice(side_poly_range);
MutableSpan<MLoop> loops = mesh.loops_for_write();
MutableSpan<MLoop> new_loops = loops.slice(side_loop_range);
MutableSpan<int> corner_verts = mesh.corner_verts_for_write();
MutableSpan<int> new_corner_verts = corner_verts.slice(side_loop_range);
MutableSpan<int> corner_edges = mesh.corner_edges_for_write();
MutableSpan<int> new_corner_edges = corner_edges.slice(side_loop_range);
/* Initialize the edges that form the sides of the extrusion. */
for (const int i : connect_edges.index_range()) {
@ -818,20 +827,20 @@ static void extrude_mesh_face_regions(Mesh &mesh,
/* Connect the selected faces to the extruded or duplicated edges and the new vertices. */
for (const int i_poly : poly_selection) {
const MPoly &poly = polys[i_poly];
for (MLoop &loop : loops.slice(poly.loopstart, poly.totloop)) {
const int i_new_vert = new_vert_indices.index_of_try(loop.v);
for (const int corner_i : IndexRange(poly.loopstart, poly.totloop)) {
const int i_new_vert = new_vert_indices.index_of_try(corner_verts[corner_i]);
if (i_new_vert != -1) {
loop.v = new_vert_range[i_new_vert];
corner_verts[corner_i] = new_vert_range[i_new_vert];
}
const int i_boundary_edge = boundary_edge_indices.index_of_try(loop.e);
const int i_boundary_edge = boundary_edge_indices.index_of_try(corner_edges[corner_i]);
if (i_boundary_edge != -1) {
loop.e = boundary_edge_range[i_boundary_edge];
corner_edges[corner_i] = boundary_edge_range[i_boundary_edge];
/* Skip the next check, an edge cannot be both a boundary edge and an inner edge. */
continue;
}
const int i_new_inner_edge = new_inner_edge_indices.index_of_try(loop.e);
const int i_new_inner_edge = new_inner_edge_indices.index_of_try(corner_edges[corner_i]);
if (i_new_inner_edge != -1) {
loop.e = new_inner_edge_range[i_new_inner_edge];
corner_edges[corner_i] = new_inner_edge_range[i_new_inner_edge];
}
}
}
@ -846,16 +855,19 @@ static void extrude_mesh_face_regions(Mesh &mesh,
const MPoly &extrude_poly = polys[edge_extruded_face_indices[i]];
fill_quad_consistent_direction(loops.slice(extrude_poly.loopstart, extrude_poly.totloop),
new_loops.slice(4 * i, 4),
new_vert_1,
new_vert_2,
new_vert_indices[extrude_index_1],
new_vert_indices[extrude_index_2],
boundary_edge_range[i],
connect_edge_range[extrude_index_1],
boundary_edge_indices[i],
connect_edge_range[extrude_index_2]);
fill_quad_consistent_direction(
corner_verts.slice(extrude_poly.loopstart, extrude_poly.totloop),
corner_edges.slice(extrude_poly.loopstart, extrude_poly.totloop),
new_corner_verts.slice(4 * i, 4),
new_corner_edges.slice(4 * i, 4),
new_vert_1,
new_vert_2,
new_vert_indices[extrude_index_1],
new_vert_indices[extrude_index_2],
boundary_edge_range[i],
connect_edge_range[extrude_index_1],
boundary_edge_indices[i],
connect_edge_range[extrude_index_2]);
}
/* Create a map of indices in the extruded vertices array to all of the indices of edges
@ -1037,7 +1049,7 @@ static void extrude_individual_mesh_faces(Mesh &mesh,
const int orig_vert_size = mesh.totvert;
const int orig_edge_size = mesh.totedge;
Span<MPoly> orig_polys = mesh.polys();
Span<MLoop> orig_loops = mesh.loops();
Span<int> orig_corner_verts = mesh.corner_verts();
/* Use a mesh for the result of the evaluation because the mesh is reallocated before
* the vertices are moved, and the evaluated result might reference an attribute. */
@ -1068,7 +1080,7 @@ static void extrude_individual_mesh_faces(Mesh &mesh,
const IndexRange duplicate_edge_range = connect_edge_range.after(extrude_corner_size);
/* Each edge selected for extrusion is extruded into a single face. */
const IndexRange side_poly_range{orig_polys.size(), duplicate_edge_range.size()};
const IndexRange side_loop_range{orig_loops.size(), side_poly_range.size() * 4};
const IndexRange side_loop_range{orig_corner_verts.size(), side_poly_range.size() * 4};
expand_mesh(mesh,
new_vert_range.size(),
@ -1082,7 +1094,8 @@ static void extrude_individual_mesh_faces(Mesh &mesh,
MutableSpan<MEdge> duplicate_edges = edges.slice(duplicate_edge_range);
MutableSpan<MPoly> polys = mesh.polys_for_write();
MutableSpan<MPoly> new_polys = polys.slice(side_poly_range);
MutableSpan<MLoop> loops = mesh.loops_for_write();
MutableSpan<int> corner_verts = mesh.corner_verts_for_write();
MutableSpan<int> corner_edges = mesh.corner_edges_for_write();
/* For every selected polygon, build the faces that form the sides of the extrusion. Filling some
* of this data like the new edges or polygons could be easily split into separate loops, which
@ -1092,12 +1105,14 @@ static void extrude_individual_mesh_faces(Mesh &mesh,
const IndexRange poly_corner_range = selected_corner_range(index_offsets, i_selection);
const MPoly &poly = polys[poly_selection[i_selection]];
Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop);
const Span<int> poly_verts = corner_verts.slice(poly.loopstart, poly.totloop);
const Span<int> poly_edges = corner_edges.slice(poly.loopstart, poly.totloop);
for (const int i : IndexRange(poly.totloop)) {
const int i_next = (i == poly.totloop - 1) ? 0 : i + 1;
const MLoop &orig_loop = poly_loops[i];
const MLoop &orig_loop_next = poly_loops[i_next];
const int orig_vert = poly_verts[i];
const int orig_vert_next = poly_verts[i_next];
const int orig_edge = poly_edges[i];
const int i_extrude = poly_corner_range[i];
const int i_extrude_next = poly_corner_range[i_next];
@ -1106,24 +1121,20 @@ static void extrude_individual_mesh_faces(Mesh &mesh,
const int new_vert = new_vert_range[i_extrude];
const int new_vert_next = new_vert_range[i_extrude_next];
const int orig_edge = orig_loop.e;
const int orig_vert = orig_loop.v;
const int orig_vert_next = orig_loop_next.v;
duplicate_edges[i_extrude] = new_edge(new_vert, new_vert_next);
new_polys[i_extrude] = new_poly(side_loop_range[i_extrude * 4], 4);
MutableSpan<MLoop> side_loops = loops.slice(side_loop_range[i_extrude * 4], 4);
side_loops[0].v = new_vert_next;
side_loops[0].e = i_duplicate_edge;
side_loops[1].v = new_vert;
side_loops[1].e = connect_edge_range[i_extrude];
side_loops[2].v = orig_vert;
side_loops[2].e = orig_edge;
side_loops[3].v = orig_vert_next;
side_loops[3].e = connect_edge_range[i_extrude_next];
MutableSpan<int> side_poly_verts = corner_verts.slice(side_loop_range[i_extrude * 4], 4);
MutableSpan<int> side_poly_edges = corner_edges.slice(side_loop_range[i_extrude * 4], 4);
side_poly_verts[0] = new_vert_next;
side_poly_edges[0] = i_duplicate_edge;
side_poly_verts[1] = new_vert;
side_poly_edges[1] = connect_edge_range[i_extrude];
side_poly_verts[2] = orig_vert;
side_poly_edges[2] = orig_edge;
side_poly_verts[3] = orig_vert_next;
side_poly_edges[3] = connect_edge_range[i_extrude_next];
connect_edges[i_extrude] = new_edge(orig_vert, new_vert);
}
@ -1153,11 +1164,11 @@ static void extrude_individual_mesh_faces(Mesh &mesh,
threading::parallel_for(poly_selection.index_range(), 1024, [&](const IndexRange range) {
for (const int i_selection : range) {
const MPoly &poly = polys[poly_selection[i_selection]];
Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop);
const Span<int> poly_verts = corner_verts.slice(poly.loopstart, poly.totloop);
const int corner_offset = index_offsets[i_selection];
for (const int i : poly_loops.index_range()) {
const int orig_index = poly_loops[i].v;
for (const int i : poly_verts.index_range()) {
const int orig_index = poly_verts[i];
new_data[corner_offset + i] = data[orig_index];
}
}
@ -1171,23 +1182,23 @@ static void extrude_individual_mesh_faces(Mesh &mesh,
threading::parallel_for(poly_selection.index_range(), 512, [&](const IndexRange range) {
for (const int i_selection : range) {
const MPoly &poly = polys[poly_selection[i_selection]];
Span<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop);
const Span<int> poly_edges = poly_edges.slice(poly.loopstart, poly.totloop);
const IndexRange poly_corner_range = selected_corner_range(index_offsets,
i_selection);
/* The data for the duplicate edge is simply a copy of the original edge's data. */
for (const int i : poly_loops.index_range()) {
const int orig_index = poly_loops[i].e;
for (const int i : poly_edges.index_range()) {
const int orig_index = poly_edges[i];
duplicate_data[poly_corner_range[i]] = data[orig_index];
}
/* For the extruded edges, mix the data from the two neighboring original edges of
* the extruded polygon. */
for (const int i : poly_loops.index_range()) {
for (const int i : poly_edges.index_range()) {
const int i_loop_prev = (i == 0) ? poly.totloop - 1 : i - 1;
const int orig_index = poly_loops[i].e;
const int orig_index_prev = poly_loops[i_loop_prev].e;
const int orig_index = poly_edges[i];
const int orig_index_prev = poly_edges[i_loop_prev];
if constexpr (std::is_same_v<T, bool>) {
/* Propagate selections with "or" instead of "at least half". */
connect_data[poly_corner_range[i]] = data[orig_index] || data[orig_index_prev];
@ -1280,12 +1291,13 @@ static void extrude_individual_mesh_faces(Mesh &mesh,
const IndexRange poly_corner_range = selected_corner_range(index_offsets, i_selection);
const MPoly &poly = polys[poly_selection[i_selection]];
MutableSpan<MLoop> poly_loops = loops.slice(poly.loopstart, poly.totloop);
MutableSpan<int> poly_verts = corner_verts.slice(poly.loopstart, poly.totloop);
MutableSpan<int> poly_edges = corner_edges.slice(poly.loopstart, poly.totloop);
for (const int i : IndexRange(poly.totloop)) {
MLoop &loop = poly_loops[i];
loop.v = new_vert_range[poly_corner_range[i]];
loop.e = duplicate_edge_range[poly_corner_range[i]];
const int corner_i = poly.loopstart + i;
poly_verts[i] = new_vert_range[poly_corner_range[i]];
poly_edges[i] = duplicate_edge_range[poly_corner_range[i]];
}
}
});

View File

@ -180,7 +180,8 @@ BLI_NOINLINE static void calculate_sphere_faces(MutableSpan<MPoly> polys, const
}
}
BLI_NOINLINE static void calculate_sphere_corners(MutableSpan<MLoop> loops,
BLI_NOINLINE static void calculate_sphere_corners(MutableSpan<int> corner_verts,
MutableSpan<int> corner_edges,
const int segments,
const int rings)
{

View File

@ -474,8 +474,7 @@ static void do_multires_bake(MultiresBakeRender *bkr,
const float(*positions)[3] = (float(*)[3])dm->getVertArray(dm);
MPoly *mpoly = dm->getPolyArray(dm);
MLoop *mloop = dm->getLoopArray(dm);
MLoopUV *mloopuv = dm->getLoopDataArray(dm, CD_MLOOPUV);
MLoopUV *mloopuv = static_cast<MLoopUV *>(dm->getLoopDataArray(dm, CD_MLOOPUV));
float *pvtangent = NULL;
ListBase threads;
@ -555,14 +554,14 @@ static void do_multires_bake(MultiresBakeRender *bkr,
handle->queue = &queue;
handle->data.mpoly = mpoly;
handle->data.material_indices = CustomData_get_layer_named(
&dm->polyData, CD_PROP_INT32, "material_index");
handle->data.mvert = mvert;
handle->data.material_indices = static_cast<const int *>(
CustomData_get_layer_named(&dm->polyData, CD_PROP_INT32, "material_index"));
handle->data.positions = positions;
handle->data.vert_normals = vert_normals;
handle->data.mloopuv = mloopuv;
BKE_image_get_tile_uv(ima, tile->tile_number, handle->data.uv_offset);
handle->data.mlooptri = mlooptri;
handle->data.corner_verts = corner_verts;
handle->data.corner_verts = dm->getCornerVertArray(dm);
handle->data.pvtangent = pvtangent;
handle->data.precomputed_normals = poly_normals; /* don't strictly need this */
handle->data.w = ibuf->x;