Fix (unreported) looptri array not being recalculated in ccgDM and emDM

In ccgDM and emDM, looptri array recalculation was being handled
directly by `*DM_getLoopTriArray` (`getLoopTriArray` callback), while
`*DM_recalcLoopTri` (`recalcLoopTri` callback) was doing nothing.

This results in the array not being recalculated when other functions
that depend on the array data called the recalc function.

This moves all the recalculation code to `*DM_recalcLoopTri` and makes
`*DM_getLoopTriArray` call that.

This commit also makes a minor change to the `getNumLoopTri` function,
so that it returns the correct number without having to recalculate the
looptri array.

Reviewed By: mont29

Differential Revision: https://developer.blender.org/D2375
This commit is contained in:
Luca Rood 2016-11-23 17:19:03 -02:00
parent 69a75b0169
commit 7fe7835d13
3 changed files with 61 additions and 59 deletions

View File

@ -230,7 +230,9 @@ static MPoly *dm_dupPolyArray(DerivedMesh *dm)
static int dm_getNumLoopTri(DerivedMesh *dm)
{
return dm->looptris.num;
const int numlooptris = poly_to_tri_count(dm->getNumPolys(dm), dm->getNumLoops(dm));
BLI_assert(ELEM(dm->looptris.num, 0, numlooptris));
return numlooptris;
}
static CustomData *dm_getVertCData(DerivedMesh *dm)

View File

@ -621,10 +621,33 @@ static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm))
/* do nothing */
}
static void emDM_recalcLoopTri(DerivedMesh *UNUSED(dm))
static void emDM_recalcLoopTri(DerivedMesh *dm)
{
/* Nothing to do: emDM tessellation is known,
* allocate and fill in with emDM_getLoopTriArray */
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMLoop *(*looptris)[3] = bmdm->em->looptris;
MLoopTri *mlooptri;
const int tottri = bmdm->em->tottri;
int i;
DM_ensure_looptri_data(dm);
mlooptri = dm->looptris.array;
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
BLI_assert(tottri == dm->looptris.num);
BM_mesh_elem_index_ensure(bmdm->em->bm, BM_FACE | BM_LOOP);
for (i = 0; i < tottri; i++) {
BMLoop **ltri = looptris[i];
MLoopTri *lt = &mlooptri[i];
ARRAY_SET_ITEMS(
lt->tri,
BM_elem_index_get(ltri[0]),
BM_elem_index_get(ltri[1]),
BM_elem_index_get(ltri[2]));
lt->poly = BM_elem_index_get(ltri[0]->f);
}
}
static const MLoopTri *emDM_getLoopTriArray(DerivedMesh *dm)
@ -633,32 +656,9 @@ static const MLoopTri *emDM_getLoopTriArray(DerivedMesh *dm)
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
}
else {
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMLoop *(*looptris)[3] = bmdm->em->looptris;
MLoopTri *mlooptri;
const int tottri = bmdm->em->tottri;
int i;
DM_ensure_looptri_data(dm);
mlooptri = dm->looptris.array;
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
BLI_assert(tottri == dm->looptris.num);
BM_mesh_elem_index_ensure(bmdm->em->bm, BM_FACE | BM_LOOP);
for (i = 0; i < tottri; i++) {
BMLoop **ltri = looptris[i];
MLoopTri *lt = &mlooptri[i];
ARRAY_SET_ITEMS(
lt->tri,
BM_elem_index_get(ltri[0]),
BM_elem_index_get(ltri[1]),
BM_elem_index_get(ltri[2]));
lt->poly = BM_elem_index_get(ltri[0]->f);
}
dm->recalcLoopTri(dm);
}
return dm->looptris.array;
}

View File

@ -4474,46 +4474,46 @@ static void ccgDM_recalcTessellation(DerivedMesh *UNUSED(dm))
/* Nothing to do: CCG handles creating its own tessfaces */
}
static void ccgDM_recalcLoopTri(DerivedMesh *UNUSED(dm))
static void ccgDM_recalcLoopTri(DerivedMesh *dm)
{
/* Nothing to do: CCG tessellation is known,
* allocate and fill in with ccgDM_getLoopTriArray */
BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE);
MLoopTri *mlooptri;
const int tottri = dm->numPolyData * 2;
int i, poly_index;
DM_ensure_looptri_data(dm);
mlooptri = dm->looptris.array;
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
BLI_assert(tottri == dm->looptris.num);
for (i = 0, poly_index = 0; i < tottri; i += 2, poly_index += 1) {
MLoopTri *lt;
lt = &mlooptri[i];
/* quad is (0, 3, 2, 1) */
lt->tri[0] = (poly_index * 4) + 0;
lt->tri[1] = (poly_index * 4) + 2;
lt->tri[2] = (poly_index * 4) + 3;
lt->poly = poly_index;
lt = &mlooptri[i + 1];
lt->tri[0] = (poly_index * 4) + 0;
lt->tri[1] = (poly_index * 4) + 1;
lt->tri[2] = (poly_index * 4) + 2;
lt->poly = poly_index;
}
BLI_rw_mutex_unlock(&loops_cache_rwlock);
}
static const MLoopTri *ccgDM_getLoopTriArray(DerivedMesh *dm)
{
BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE);
if (dm->looptris.array) {
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
}
else {
MLoopTri *mlooptri;
const int tottri = dm->numPolyData * 2;
int i, poly_index;
DM_ensure_looptri_data(dm);
mlooptri = dm->looptris.array;
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
BLI_assert(tottri == dm->looptris.num);
for (i = 0, poly_index = 0; i < tottri; i += 2, poly_index += 1) {
MLoopTri *lt;
lt = &mlooptri[i];
/* quad is (0, 3, 2, 1) */
lt->tri[0] = (poly_index * 4) + 0;
lt->tri[1] = (poly_index * 4) + 2;
lt->tri[2] = (poly_index * 4) + 3;
lt->poly = poly_index;
lt = &mlooptri[i + 1];
lt->tri[0] = (poly_index * 4) + 0;
lt->tri[1] = (poly_index * 4) + 1;
lt->tri[2] = (poly_index * 4) + 2;
lt->poly = poly_index;
}
dm->recalcLoopTri(dm);
}
BLI_rw_mutex_unlock(&loops_cache_rwlock);
return dm->looptris.array;
}