Modifiers: Simple Deform & Build, DerivedMesh → Mesh

This commit introduces `EditMeshData`. The fields in this struct are
extracted from `EditDerivedBMesh` into their own struct `EditMeshData`,
which can then also be used by the `Mesh` struct. This allows passing
deformed vertices efficiently to the draw routines.

The modifier code constructs a new Mesh instead of writing to ob->data;
even when ob->data is a CoW copy, it can still be used by different
objects and thus shouldn't be modified by a modifier.
This commit is contained in:
2018-04-19 11:03:58 +02:00
parent be4df85919
commit 7efc75c709
11 changed files with 374 additions and 183 deletions

View File

@@ -388,6 +388,36 @@ void BKE_mesh_ensure_skin_customdata(Mesh *me)
}
}
bool BKE_mesh_ensure_edit_data(struct Mesh *me)
{
if (me->emd != NULL) {
return false;
}
me->emd = MEM_callocN(sizeof(EditMeshData), "EditMeshData");
return true;
}
bool BKE_mesh_clear_edit_data(struct Mesh *me)
{
if (me->emd == NULL) {
return false;
}
if (me->emd->polyCos != NULL)
MEM_freeN((void *)me->emd->polyCos);
if (me->emd->polyNos != NULL)
MEM_freeN((void *)me->emd->polyNos);
if (me->emd->vertexCos != NULL)
MEM_freeN((void *)me->emd->vertexCos);
if (me->emd->vertexNos != NULL)
MEM_freeN((void *)me->emd->vertexNos);
MEM_SAFE_FREE(me->emd);
return true;
}
bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me)
{
BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL;
@@ -481,6 +511,7 @@ void BKE_mesh_free(Mesh *me)
BKE_animdata_free(&me->id, false);
BKE_mesh_batch_cache_free(me);
BKE_mesh_clear_edit_data(me);
CustomData_free(&me->vdata, me->totvert);
CustomData_free(&me->edata, me->totedge);
@@ -580,6 +611,52 @@ void BKE_mesh_copy_data(Main *bmain, Mesh *me_dst, const Mesh *me_src, const int
}
}
static Mesh *mesh_from_template_ex(
Mesh *me_src,
int numVerts, int numEdges, int numTessFaces,
int numLoops, int numPolys,
CustomDataMask mask)
{
const bool do_tessface = ((me_src->totface != 0) && (me_src->totpoly == 0)); /* only do tessface if we have no polys */
Mesh *me_dst = MEM_callocN(sizeof(struct Mesh), "Mesh");
BKE_mesh_init(me_dst);
me_dst->mat = MEM_dupallocN(me_src->mat);
me_dst->mselect = MEM_dupallocN(me_dst->mselect);
me_dst->totvert = numVerts;
me_dst->totedge = numEdges;
me_dst->totloop = numLoops;
me_dst->totpoly = numPolys;
CustomData_copy(&me_src->vdata, &me_dst->vdata, mask, CD_CALLOC, numVerts);
CustomData_copy(&me_src->edata, &me_dst->edata, mask, CD_CALLOC, numEdges);
CustomData_copy(&me_src->ldata, &me_dst->ldata, mask, CD_CALLOC, numLoops);
CustomData_copy(&me_src->pdata, &me_dst->pdata, mask, CD_CALLOC, numPolys);
if (do_tessface) {
CustomData_copy(&me_src->fdata, &me_dst->fdata, mask, CD_CALLOC, numTessFaces);
}
else {
mesh_tessface_clear_intern(me_dst, false);
}
BKE_mesh_update_customdata_pointers(me_dst, false);
return me_dst;
}
Mesh * BKE_mesh_from_template(Mesh *me_src,
int numVerts, int numEdges, int numTessFaces,
int numLoops, int numPolys)
{
return mesh_from_template_ex(
me_src,
numVerts, numEdges, numTessFaces,
numLoops, numPolys,
CD_MASK_EVERYTHING);
}
Mesh *BKE_mesh_copy(Main *bmain, const Mesh *me)
{
Mesh *me_copy;