104 remaining uses of MLoop

This commit is contained in:
Hans Goudey 2022-12-04 22:58:47 -06:00
parent bf661c0a26
commit d0c2858714
50 changed files with 639 additions and 615 deletions

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. */
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;