All uses of MLoop besides BKE_mesh_merge_verts removed

This commit is contained in:
Hans Goudey 2022-12-06 16:23:54 -06:00
parent d3097d941b
commit 38c51e1ce9
7 changed files with 133 additions and 56 deletions

View File

@ -138,7 +138,8 @@ struct DerivedMesh {
*/
void (*copyVertArray)(DerivedMesh *dm, float (*r_positions)[3]);
void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *r_edge);
void (*copyLoopArray)(DerivedMesh *dm, struct MLoop *r_loop);
void (*copyCornerVertArray)(DerivedMesh *dm, int *r_corner_verts);
void (*copyCornerEdgeArray)(DerivedMesh *dm, int *r_corner_edges);
void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *r_poly);
/** Return a pointer to the entire array of vert/edge/face custom data

View File

@ -121,18 +121,32 @@ static MEdge *dm_getEdgeArray(DerivedMesh *dm)
return medge;
}
static MLoop *dm_getLoopArray(DerivedMesh *dm)
static int *dm_getCornerVertArray(DerivedMesh *dm)
{
MLoop *mloop = (MLoop *)CustomData_get_layer(&dm->loopData, CD_MLOOP);
int *corner_verts = (int *)CustomData_get_layer(&dm->loopData, CD_MLOOP);
if (!mloop) {
mloop = (MLoop *)CustomData_add_layer(
if (!corner_verts) {
corner_verts = (int *)CustomData_add_layer(
&dm->loopData, CD_MLOOP, CD_SET_DEFAULT, nullptr, dm->getNumLoops(dm));
CustomData_set_layer_flag(&dm->loopData, CD_MLOOP, CD_FLAG_TEMPORARY);
dm->copyLoopArray(dm, mloop);
dm->copyCornerVertArray(dm, corner_verts);
}
return mloop;
return corner_verts;
}
static int *dm_getCornerEdgeArray(DerivedMesh *dm)
{
int *corner_edges = (int *)CustomData_get_layer(&dm->loopData, CD_MLOOP);
if (!corner_edges) {
corner_edges = (int *)CustomData_add_layer(
&dm->loopData, CD_MLOOP, CD_SET_DEFAULT, nullptr, dm->getNumLoops(dm));
CustomData_set_layer_flag(&dm->loopData, CD_MLOOP, CD_FLAG_TEMPORARY);
dm->copyCornerEdgeArray(dm, corner_edges);
}
return corner_edges;
}
static MPoly *dm_getPolyArray(DerivedMesh *dm)
@ -185,7 +199,8 @@ void DM_init_funcs(DerivedMesh *dm)
/* default function implementations */
dm->getVertArray = dm_getVertArray;
dm->getEdgeArray = dm_getEdgeArray;
dm->getLoopArray = dm_getLoopArray;
dm->getCornerVertArray = dm_getCornerVertArray;
dm->getCornerEdgeArray = dm_getCornerEdgeArray;
dm->getPolyArray = dm_getPolyArray;
dm->getLoopTriArray = dm_getLoopTriArray;

View File

@ -88,10 +88,16 @@ static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *r_edge)
memcpy(r_edge, cddm->medge, sizeof(*r_edge) * dm->numEdgeData);
}
static void cdDM_copyLoopArray(DerivedMesh *dm, MLoop *r_loop)
static void cdDM_copyCornerVertArray(DerivedMesh *dm, int *r_corner_verts)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
memcpy(r_loop, cddm->mloop, sizeof(*r_loop) * dm->numLoopData);
memcpy(r_corner_verts, cddm->corner_verts, sizeof(*r_corner_verts) * dm->numLoopData);
}
static void cdDM_copyCornerEdgeArray(DerivedMesh *dm, int *r_corner_edges)
{
CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
memcpy(r_corner_edges, cddm->corner_edges, sizeof(*r_corner_edges) * dm->numLoopData);
}
static void cdDM_copyPolyArray(DerivedMesh *dm, MPoly *r_poly)
@ -122,8 +128,12 @@ static void cdDM_recalc_looptri(DerivedMesh *dm)
DM_ensure_looptri_data(dm);
BLI_assert(totpoly == 0 || cddm->dm.looptris.array_wip != NULL);
BKE_mesh_recalc_looptri(
cddm->mloop, cddm->mpoly, cddm->positions, totloop, totpoly, cddm->dm.looptris.array_wip);
BKE_mesh_recalc_looptri(cddm->corner_verts,
cddm->mpoly,
cddm->positions,
totloop,
totpoly,
cddm->dm.looptris.array_wip);
BLI_assert(cddm->dm.looptris.array == NULL);
atomic_cas_ptr(
@ -167,7 +177,8 @@ static CDDerivedMesh *cdDM_create(const char *desc)
dm->copyVertArray = cdDM_copyVertArray;
dm->copyEdgeArray = cdDM_copyEdgeArray;
dm->copyLoopArray = cdDM_copyLoopArray;
dm->copyCornerVertArray = cdDM_copyCornerVertArray;
dm->copyCornerEdgeArray = cdDM_copyCornerEdgeArray;
dm->copyPolyArray = cdDM_copyPolyArray;
dm->getVertDataArray = DM_get_vert_data_layer;
@ -223,7 +234,8 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh,
* or dirty normals. */
cddm->vert_normals = BKE_mesh_vertex_normals_ensure(mesh);
cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
cddm->corner_verts = CustomData_get_layer(&dm->loopData, CD_MLOOP);
cddm->corner_edges = CustomData_get_layer(&dm->loopData, CD_MLOOP);
cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
#if 0
cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);

View File

@ -1852,7 +1852,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(MRecast), "MRecast", 1, N_("Recast"), nullptr, nullptr, nullptr, nullptr},
/* 25: CD_MPOLY */
{sizeof(MPoly), "MPoly", 1, N_("NGon Face"), nullptr, nullptr, nullptr, nullptr, nullptr},
/* 26: CD_MLOOP */
/* 26: CD_MLOOP */ /* DEPRECATED*/
{sizeof(MLoop),
"MLoop",
1,

View File

@ -214,15 +214,14 @@ void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old)
const Span<MVert> verts(static_cast<const MVert *>(CustomData_get_layer(&me->vdata, CD_MVERT)),
me->totvert);
const Span<MPoly> polys = me->polys();
MutableSpan<MLoop> loops = me->loops_for_write();
mesh_calc_edges_mdata(verts.data(),
(MFace *)CustomData_get_layer(&me->fdata, CD_MFACE),
loops.data(),
static_cast<MLoop *>(CustomData_get_layer(&me->ldata, CD_MLOOP)),
polys.data(),
verts.size(),
me->totface,
loops.size(),
me->totloop,
polys.size(),
use_old,
&medge,
@ -938,7 +937,8 @@ int BKE_mesh_mface_index_validate(MFace *mface, CustomData *fdata, int mfindex,
return nr;
}
static int mesh_tessface_calc(CustomData *fdata,
static int mesh_tessface_calc(Mesh *mesh,
CustomData *fdata,
CustomData *ldata,
CustomData *pdata,
float (*positions)[3],
@ -955,7 +955,6 @@ static int mesh_tessface_calc(CustomData *fdata,
const int looptri_num = poly_to_tri_count(totpoly, totloop);
const MPoly *mp, *mpoly;
const MLoop *ml, *mloop;
MFace *mface, *mf;
MemArena *arena = nullptr;
int *mface_to_poly_map;
@ -964,7 +963,7 @@ static int mesh_tessface_calc(CustomData *fdata,
uint j;
mpoly = (const MPoly *)CustomData_get_layer(pdata, CD_MPOLY);
mloop = (const MLoop *)CustomData_get_layer(ldata, CD_MLOOP);
const Span<int> corner_verts = mesh->corner_verts();
const int *material_indices = static_cast<const int *>(
CustomData_get_layer_named(pdata, CD_PROP_INT32, "material_index"));
@ -997,9 +996,9 @@ static int mesh_tessface_calc(CustomData *fdata,
l1 = mp_loopstart + i1; \
l2 = mp_loopstart + i2; \
l3 = mp_loopstart + i3; \
mf->v1 = mloop[l1].v; \
mf->v2 = mloop[l2].v; \
mf->v3 = mloop[l3].v; \
mf->v1 = corner_verts[l1]; \
mf->v2 = corner_verts[l2]; \
mf->v3 = corner_verts[l3]; \
mf->v4 = 0; \
lidx[0] = l1; \
lidx[1] = l2; \
@ -1020,10 +1019,10 @@ static int mesh_tessface_calc(CustomData *fdata,
l2 = mp_loopstart + 1; /* EXCEPTION */ \
l3 = mp_loopstart + 2; /* EXCEPTION */ \
l4 = mp_loopstart + 3; /* EXCEPTION */ \
mf->v1 = mloop[l1].v; \
mf->v2 = mloop[l2].v; \
mf->v3 = mloop[l3].v; \
mf->v4 = mloop[l4].v; \
mf->v1 = corner_verts[l1]; \
mf->v2 = corner_verts[l2]; \
mf->v3 = corner_verts[l3]; \
mf->v4 = corner_verts[l4]; \
lidx[0] = l1; \
lidx[1] = l2; \
lidx[2] = l3; \
@ -1070,10 +1069,10 @@ static int mesh_tessface_calc(CustomData *fdata,
zero_v3(normal);
/* Calculate the normal, flipped: to get a positive 2D cross product. */
ml = mloop + mp_loopstart;
co_prev = positions[ml[mp_totloop - 1].v];
for (j = 0; j < mp_totloop; j++, ml++) {
co_curr = positions[ml->v];
co_prev = positions[corner_verts[mp_loopstart + mp_totloop - 1]];
for (j = 0; j < mp_totloop; j++) {
const int vert_i = corner_verts[mp_loopstart + j];
co_curr = positions[vert_i];
add_newell_cross_v3_v3v3(normal, co_prev, co_curr);
co_prev = co_curr;
}
@ -1084,9 +1083,9 @@ static int mesh_tessface_calc(CustomData *fdata,
/* Project verts to 2D. */
axis_dominant_v3_to_m3_negate(axis_mat, normal);
ml = mloop + mp_loopstart;
for (j = 0; j < mp_totloop; j++, ml++) {
mul_v2_m3v3(projverts[j], axis_mat, positions[ml->v]);
for (j = 0; j < mp_totloop; j++) {
const int vert_i = corner_verts[mp_loopstart + j];
mul_v2_m3v3(projverts[j], axis_mat, positions[vert_i]);
}
BLI_polyfill_calc_arena(projverts, mp_totloop, 1, tris, arena);
@ -1104,9 +1103,9 @@ static int mesh_tessface_calc(CustomData *fdata,
l2 = mp_loopstart + tri[1];
l3 = mp_loopstart + tri[2];
mf->v1 = mloop[l1].v;
mf->v2 = mloop[l2].v;
mf->v3 = mloop[l3].v;
mf->v1 = corner_verts[l1];
mf->v2 = corner_verts[l2];
mf->v3 = corner_verts[l3];
mf->v4 = 0;
lidx[0] = l1;
@ -1185,7 +1184,8 @@ static int mesh_tessface_calc(CustomData *fdata,
void BKE_mesh_tessface_calc(Mesh *mesh)
{
mesh->totface = mesh_tessface_calc(&mesh->fdata,
mesh->totface = mesh_tessface_calc(mesh,
&mesh->fdata,
&mesh->ldata,
&mesh->pdata,
BKE_mesh_positions_for_write(mesh),

View File

@ -1038,7 +1038,7 @@ static void copyFinalLoopArray_task_cb(void *__restrict userdata,
int *corner_verts = data->corner_verts;
int *corner_edges = data->corner_edges;
size_t loop_index = 4 * (size_t)grid_index * (grid_size - 1) * (grid_size - 1);
size_t loop_i = 4 * (size_t)grid_index * (grid_size - 1) * (grid_size - 1);
for (int S = 0; S < num_verts; S++) {
for (int y = 0; y < grid_size - 1; y++) {
for (int x = 0; x < grid_size - 1; x++) {
@ -1048,24 +1048,26 @@ static void copyFinalLoopArray_task_cb(void *__restrict userdata,
const int v3 = getFaceIndex(ss, f, S, x + 1, y + 1, edge_size, grid_size);
const int v4 = getFaceIndex(ss, f, S, x + 1, y + 0, edge_size, grid_size);
corner_verts[loop_index] = v1;
corner_edges[loop_index] = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v1, v2));
loop_index++;
corner_verts[loop_index] = v2;
corner_edges[loop_index] = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v2, v3));
loop_index++;
corner_verts[loop_index] = v3;
corner_edges[loop_index] = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v3, v4));
loop_index++;
corner_verts[loop_index] = v4;
corner_edges[loop_index] = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v4, v1));
loop_index++;
if (corner_verts) {
corner_verts[loop_i + 0] = v1;
corner_verts[loop_i + 1] = v2;
corner_verts[loop_i + 2] = v3;
corner_verts[loop_i + 3] = v4;
}
if (corner_edges) {
corner_edges[loop_i + 0] = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v1, v2));
corner_edges[loop_i + 1] = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v2, v3));
corner_edges[loop_i + 2] = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v3, v4));
corner_edges[loop_i + 3] = POINTER_AS_UINT(BLI_edgehash_lookup(ccgdm->ehash, v4, v1));
}
loop_i += 4;
}
}
}
}
static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
static void ccgDM_copyFinalCornerVertArray(DerivedMesh *dm, int *r_corner_verts)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
CCGSubSurf *ss = ccgdm->ss;
@ -1090,7 +1092,53 @@ static void ccgDM_copyFinalLoopArray(DerivedMesh *dm, MLoop *mloop)
CopyFinalLoopArrayData data;
data.ccgdm = ccgdm;
data.mloop = mloop;
data.corner_verts = r_corner_verts;
data.corner_edges = NULL;
data.grid_size = ccgSubSurf_getGridSize(ss);
data.grid_offset = dm->getGridOffset(dm);
data.edge_size = ccgSubSurf_getEdgeSize(ss);
/* NOTE: For a dense subdivision we've got enough work for each face and
* hence can dedicate whole thread to single face. For less dense
* subdivision we handle multiple faces per thread.
*/
data.mloop_index = data.grid_size >= 5 ? 1 : 8;
TaskParallelSettings settings;
BLI_parallel_range_settings_defaults(&settings);
settings.min_iter_per_thread = 1;
BLI_task_parallel_range(
0, ccgSubSurf_getNumFaces(ss), &data, copyFinalLoopArray_task_cb, &settings);
}
static void ccgDM_copyFinalCornerEdgeArray(DerivedMesh *dm, int *r_corner_edges)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm;
CCGSubSurf *ss = ccgdm->ss;
if (!ccgdm->ehash) {
BLI_mutex_lock(&ccgdm->loops_cache_lock);
if (!ccgdm->ehash) {
MEdge *medge;
EdgeHash *ehash;
ehash = BLI_edgehash_new_ex(__func__, ccgdm->dm.numEdgeData);
medge = ccgdm->dm.getEdgeArray((DerivedMesh *)ccgdm);
for (int i = 0; i < ccgdm->dm.numEdgeData; i++) {
BLI_edgehash_insert(ehash, medge[i].v1, medge[i].v2, POINTER_FROM_INT(i));
}
atomic_cas_ptr((void **)&ccgdm->ehash, ccgdm->ehash, ehash);
}
BLI_mutex_unlock(&ccgdm->loops_cache_lock);
}
CopyFinalLoopArrayData data;
data.ccgdm = ccgdm;
data.corner_verts = NULL;
data.corner_edges = r_corner_edges;
data.grid_size = ccgSubSurf_getGridSize(ss);
data.grid_offset = dm->getGridOffset(dm);
data.edge_size = ccgSubSurf_getEdgeSize(ss);
@ -1499,7 +1547,8 @@ static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm)
ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray;
ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray;
ccgdm->dm.copyLoopArray = ccgDM_copyFinalLoopArray;
ccgdm->dm.copyCornerVertArray = ccgDM_copyFinalCornerVertArray;
ccgdm->dm.copyCornerEdgeArray = ccgDM_copyFinalCornerEdgeArray;
ccgdm->dm.copyPolyArray = ccgDM_copyFinalPolyArray;
ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer;

View File

@ -530,7 +530,7 @@ static void generate_margin(ImBuf *ibuf,
totedge = dm->getNumEdges(dm);
totloop = dm->getNumLoops(dm);
mpoly = dm->getPolyArray(dm);
corner_edges = dm->getLoopArray(dm);
corner_edges = dm->getCornerEdgeArray(dm);
mloopuv = (MLoopUV const *)dm->getLoopDataArray(dm, CD_MLOOPUV);
looptri = dm->getLoopTriArray(dm);