diff options
author | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-04-19 12:03:58 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-05-01 19:02:17 +0300 |
commit | 7efc75c7092b085fe3f5ef2dcab3669d466dfadc (patch) | |
tree | cbadfa4924b27dbd39f362025538857983c60d6d /source/blender/blenkernel | |
parent | be4df85919b42cb2cf8a01c904a8552c5c173944 (diff) |
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.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 26 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/editderivedmesh.c | 114 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 77 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 102 |
5 files changed, 233 insertions, 94 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 25ea73827c9..f0b6522f525 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -93,6 +93,14 @@ struct Mesh *BKE_mesh_copy(struct Main *bmain, const struct Mesh *me); void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd); void BKE_mesh_ensure_skin_customdata(struct Mesh *me); +struct Mesh * BKE_mesh_from_template( + struct Mesh *me_src, + int numVerts, int numEdges, int numTessFaces, + int numLoops, int numPolys); + +bool BKE_mesh_ensure_edit_data(struct Mesh *me); +bool BKE_mesh_clear_edit_data(struct Mesh *me); + bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me); bool BKE_mesh_clear_facemap_customdata(struct Mesh *me); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index c2e92136632..2c69bc90acb 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1162,7 +1162,10 @@ DerivedMesh *mesh_create_derived_for_modifier( if (mti->type == eModifierTypeType_OnlyDeform) { int numVerts; - float (*deformedVerts)[3] = BKE_mesh_vertexCos_get(me, &numVerts); + /* Always get the vertex coordinates from the original mesh. Otherwise + * there is the risk of deforming already-deformed coordinates. */ + Mesh *mesh_orig_id = (Mesh *)DEG_get_original_id(&me->id); + float (*deformedVerts)[3] = BKE_mesh_vertexCos_get(mesh_orig_id, &numVerts); modwrap_deformVerts(md, depsgraph, ob, NULL, deformedVerts, numVerts, 0); dm = mesh_create_derived(me, deformedVerts); @@ -1748,6 +1751,9 @@ static void mesh_calc_modifiers( DerivedMesh **r_deform, DerivedMesh **r_final) { Mesh *me = ob->data; + /* Always get the vertex coordinates from the original mesh. Otherwise + * there is the risk of deforming already-deformed coordinates. */ + Mesh *mesh_orig_id = (Mesh *)DEG_get_original_id(&me->id); ModifierData *firstmd, *md, *previewmd = NULL; CDMaskLink *datamasks, *curr; /* XXX Always copying POLYINDEX, else tessellated data are no more valid! */ @@ -1837,7 +1843,7 @@ static void mesh_calc_modifiers( if (mti->type == eModifierTypeType_OnlyDeform && !sculpt_dyntopo) { if (!deformedVerts) - deformedVerts = BKE_mesh_vertexCos_get(me, &numVerts); + deformedVerts = BKE_mesh_vertexCos_get(mesh_orig_id, &numVerts); modwrap_deformVerts(md, depsgraph, ob, NULL, deformedVerts, numVerts, deform_app_flags); } @@ -1870,7 +1876,7 @@ static void mesh_calc_modifiers( if (inputVertexCos) deformedVerts = inputVertexCos; else - deformedVerts = BKE_mesh_vertexCos_get(me, &numVerts); + deformedVerts = BKE_mesh_vertexCos_get(mesh_orig_id, &numVerts); } @@ -1967,7 +1973,7 @@ static void mesh_calc_modifiers( dm->getVertCos(dm, deformedVerts); } else { - deformedVerts = BKE_mesh_vertexCos_get(me, &numVerts); + deformedVerts = BKE_mesh_vertexCos_get(mesh_orig_id, &numVerts); } } @@ -2467,6 +2473,11 @@ static void editbmesh_calc_modifiers( *r_cage = dm; } else { + struct Mesh *mesh = ob->data; + if (mesh->id.tag & LIB_TAG_COPY_ON_WRITE) { + BKE_mesh_ensure_edit_data(mesh); + mesh->emd->vertexCos = MEM_dupallocN(deformedVerts); + } *r_cage = getEditDerivedBMesh( em, ob, mask, deformedVerts ? MEM_dupallocN(deformedVerts) : NULL); @@ -2504,6 +2515,13 @@ static void editbmesh_calc_modifiers( } else { /* this is just a copy of the editmesh, no need to calc normals */ + struct Mesh *mesh = ob->data; + if (mesh->id.tag & LIB_TAG_COPY_ON_WRITE) { + BKE_mesh_ensure_edit_data(mesh); + if (mesh->emd->vertexCos != NULL) + MEM_freeN((void *)mesh->emd->vertexCos); + mesh->emd->vertexCos = MEM_dupallocN(deformedVerts); + } *r_final = getEditDerivedBMesh(em, ob, dataMask, deformedVerts); deformedVerts = NULL; diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c index 1e211d1c4af..f5e5a37c7d7 100644 --- a/source/blender/blenkernel/intern/editderivedmesh.c +++ b/source/blender/blenkernel/intern/editderivedmesh.c @@ -56,6 +56,7 @@ #include "DNA_scene_types.h" #include "DNA_object_types.h" +#include "DNA_mesh_types.h" #include "MEM_guardedalloc.h" @@ -64,14 +65,7 @@ typedef struct EditDerivedBMesh { BMEditMesh *em; - /** when set, \a vertexNos, polyNos are lazy initialized */ - const float (*vertexCos)[3]; - - /** lazy initialize (when \a vertexCos is set) */ - float const (*vertexNos)[3]; - float const (*polyNos)[3]; - /** also lazy init but dont depend on \a vertexCos */ - const float (*polyCos)[3]; + EditMeshData emd; } EditDerivedBMesh; /* -------------------------------------------------------------------- */ @@ -81,7 +75,7 @@ static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm); static void emDM_ensureVertNormals(EditDerivedBMesh *bmdm) { - if (bmdm->vertexCos && (bmdm->vertexNos == NULL)) { + if (bmdm->emd.vertexCos && (bmdm->emd.vertexNos == NULL)) { BMesh *bm = bmdm->em->bm; const float (*vertexCos)[3], (*polyNos)[3]; @@ -92,19 +86,19 @@ static void emDM_ensureVertNormals(EditDerivedBMesh *bmdm) BM_mesh_elem_index_ensure(bm, BM_FACE); - polyNos = bmdm->polyNos; - vertexCos = bmdm->vertexCos; + polyNos = bmdm->emd.polyNos; + vertexCos = bmdm->emd.vertexCos; vertexNos = MEM_callocN(sizeof(*vertexNos) * bm->totvert, __func__); BM_verts_calc_normal_vcos(bm, polyNos, vertexCos, vertexNos); - bmdm->vertexNos = (const float (*)[3])vertexNos; + bmdm->emd.vertexNos = (const float (*)[3])vertexNos; } } static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm) { - if (bmdm->vertexCos && (bmdm->polyNos == NULL)) { + if (bmdm->emd.vertexCos && (bmdm->emd.polyNos == NULL)) { BMesh *bm = bmdm->em->bm; const float (*vertexCos)[3]; float (*polyNos)[3]; @@ -117,7 +111,7 @@ static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm) polyNos = MEM_mallocN(sizeof(*polyNos) * bm->totface, __func__); - vertexCos = bmdm->vertexCos; + vertexCos = bmdm->emd.vertexCos; BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) { BM_elem_index_set(efa, i); /* set_inline */ @@ -125,13 +119,13 @@ static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm) } bm->elem_index_dirty &= ~BM_FACE; - bmdm->polyNos = (const float (*)[3])polyNos; + bmdm->emd.polyNos = (const float (*)[3])polyNos; } } static void emDM_ensurePolyCenters(EditDerivedBMesh *bmdm) { - if (bmdm->polyCos == NULL) { + if (bmdm->emd.polyCos == NULL) { BMesh *bm = bmdm->em->bm; float (*polyCos)[3]; @@ -141,9 +135,9 @@ static void emDM_ensurePolyCenters(EditDerivedBMesh *bmdm) polyCos = MEM_mallocN(sizeof(*polyCos) * bm->totface, __func__); - if (bmdm->vertexCos) { + if (bmdm->emd.vertexCos) { const float (*vertexCos)[3]; - vertexCos = bmdm->vertexCos; + vertexCos = bmdm->emd.vertexCos; BM_mesh_elem_index_ensure(bm, BM_VERT); @@ -157,7 +151,7 @@ static void emDM_ensurePolyCenters(EditDerivedBMesh *bmdm) } } - bmdm->polyCos = (const float (*)[3])polyCos; + bmdm->emd.polyCos = (const float (*)[3])polyCos; } } @@ -193,9 +187,9 @@ static void emDM_calcLoopNormalsSpaceArray( emDM_ensurePolyNormals(bmdm); dm->dirty &= ~DM_DIRTY_NORMALS; - vertexCos = bmdm->vertexCos; - vertexNos = bmdm->vertexNos; - polyNos = bmdm->polyNos; + vertexCos = bmdm->emd.vertexCos; + vertexNos = bmdm->emd.vertexNos; + polyNos = bmdm->emd.polyNos; loopNos = dm->getLoopDataArray(dm, CD_NORMAL); if (!loopNos) { @@ -247,7 +241,7 @@ static void emDM_calc_loop_tangents( return; } - const float (*poly_normals)[3] = bmdm->polyNos; + const float (*poly_normals)[3] = bmdm->emd.polyNos; const float (*loop_normals)[3] = CustomData_get_layer(&dm->loopData, CD_NORMAL); const float (*vert_orco)[3] = dm->getVertDataArray(dm, CD_ORCO); /* can be NULL */ BKE_editmesh_loop_tangent_calc( @@ -311,13 +305,13 @@ static void emDM_foreachMappedVert( BMIter iter; int i; - if (bmdm->vertexCos) { - const float (*vertexCos)[3] = bmdm->vertexCos; + if (bmdm->emd.vertexCos) { + const float (*vertexCos)[3] = bmdm->emd.vertexCos; const float (*vertexNos)[3]; if (flag & DM_FOREACH_USE_NORMAL) { emDM_ensureVertNormals(bmdm); - vertexNos = bmdm->vertexNos; + vertexNos = bmdm->emd.vertexNos; } else { vertexNos = NULL; @@ -346,14 +340,14 @@ static void emDM_foreachMappedEdge( BMIter iter; int i; - if (bmdm->vertexCos) { + if (bmdm->emd.vertexCos) { BM_mesh_elem_index_ensure(bm, BM_VERT); BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) { func(userData, i, - bmdm->vertexCos[BM_elem_index_get(eed->v1)], - bmdm->vertexCos[BM_elem_index_get(eed->v2)]); + bmdm->emd.vertexCos[BM_elem_index_get(eed->v1)], + bmdm->emd.vertexCos[BM_elem_index_get(eed->v2)]); } } else { @@ -378,7 +372,7 @@ static void emDM_foreachMappedLoop( BMFace *efa; BMIter iter; - const float (*vertexCos)[3] = bmdm->vertexCos; + const float (*vertexCos)[3] = bmdm->emd.vertexCos; int f_idx; BM_mesh_elem_index_ensure(bm, BM_VERT); @@ -411,11 +405,11 @@ static void emDM_foreachMappedFaceCenter( int i; emDM_ensurePolyCenters(bmdm); - polyCos = bmdm->polyCos; /* always set */ + polyCos = bmdm->emd.polyCos; /* always set */ if (flag & DM_FOREACH_USE_NORMAL) { emDM_ensurePolyNormals(bmdm); - polyNos = bmdm->polyNos; /* maybe NULL */ + polyNos = bmdm->emd.polyNos; /* maybe NULL */ } else { polyNos = NULL; @@ -444,9 +438,9 @@ static void emDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3]) int i; if (bm->totvert) { - if (bmdm->vertexCos) { + if (bmdm->emd.vertexCos) { BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { - minmax_v3v3_v3(r_min, r_max, bmdm->vertexCos[i]); + minmax_v3v3_v3(r_min, r_max, bmdm->emd.vertexCos[i]); } } else { @@ -526,8 +520,8 @@ static void emDM_getVert(DerivedMesh *dm, int index, MVert *r_vert) // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */ bmvert_to_mvert(bm, ev, r_vert); - if (bmdm->vertexCos) - copy_v3_v3(r_vert->co, bmdm->vertexCos[index]); + if (bmdm->emd.vertexCos) + copy_v3_v3(r_vert->co, bmdm->emd.vertexCos[index]); } static void emDM_getVertCo(DerivedMesh *dm, int index, float r_co[3]) @@ -540,8 +534,8 @@ static void emDM_getVertCo(DerivedMesh *dm, int index, float r_co[3]) return; } - if (bmdm->vertexCos) { - copy_v3_v3(r_co, bmdm->vertexCos[index]); + if (bmdm->emd.vertexCos) { + copy_v3_v3(r_co, bmdm->emd.vertexCos[index]); } else { BMVert *ev; @@ -564,9 +558,9 @@ static void emDM_getVertNo(DerivedMesh *dm, int index, float r_no[3]) } - if (bmdm->vertexCos) { + if (bmdm->emd.vertexCos) { emDM_ensureVertNormals(bmdm); - copy_v3_v3(r_no, bmdm->vertexNos[index]); + copy_v3_v3(r_no, bmdm->emd.vertexNos[index]); } else { BMVert *ev; @@ -588,9 +582,9 @@ static void emDM_getPolyNo(DerivedMesh *dm, int index, float r_no[3]) return; } - if (bmdm->vertexCos) { + if (bmdm->emd.vertexCos) { emDM_ensurePolyNormals(bmdm); - copy_v3_v3(r_no, bmdm->polyNos[index]); + copy_v3_v3(r_no, bmdm->emd.polyNos[index]); } else { BMFace *efa; @@ -665,11 +659,11 @@ static void emDM_copyVertArray(DerivedMesh *dm, MVert *r_vert) BMIter iter; const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT); - if (bmdm->vertexCos) { + if (bmdm->emd.vertexCos) { int i; BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { - copy_v3_v3(r_vert->co, bmdm->vertexCos[i]); + copy_v3_v3(r_vert->co, bmdm->emd.vertexCos[i]); normal_float_to_short_v3(r_vert->no, eve->no); r_vert->flag = BM_vert_flag_to_mflag(eve); @@ -873,9 +867,9 @@ static void emDM_getVertCos(DerivedMesh *dm, float (*r_cos)[3]) BMIter iter; int i; - if (bmdm->vertexCos) { + if (bmdm->emd.vertexCos) { BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) { - copy_v3_v3(r_cos[i], bmdm->vertexCos[i]); + copy_v3_v3(r_cos[i], bmdm->emd.vertexCos[i]); } } else { @@ -890,18 +884,18 @@ static void emDM_release(DerivedMesh *dm) EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm; if (DM_release(dm)) { - if (bmdm->vertexCos) { - MEM_freeN((void *)bmdm->vertexCos); - if (bmdm->vertexNos) { - MEM_freeN((void *)bmdm->vertexNos); + if (bmdm->emd.vertexCos) { + MEM_freeN((void *)bmdm->emd.vertexCos); + if (bmdm->emd.vertexNos) { + MEM_freeN((void *)bmdm->emd.vertexNos); } - if (bmdm->polyNos) { - MEM_freeN((void *)bmdm->polyNos); + if (bmdm->emd.polyNos) { + MEM_freeN((void *)bmdm->emd.polyNos); } } - if (bmdm->polyCos) { - MEM_freeN((void *)bmdm->polyCos); + if (bmdm->emd.polyCos) { + MEM_freeN((void *)bmdm->emd.polyCos); } MEM_freeN(bmdm); @@ -1006,7 +1000,7 @@ DerivedMesh *getEditDerivedBMesh( bmdm->dm.release = emDM_release; - bmdm->vertexCos = (const float (*)[3])vertexCos; + bmdm->emd.vertexCos = (const float (*)[3])vertexCos; bmdm->dm.deformedOnly = (vertexCos != NULL); const int cd_dvert_offset = (data_mask & CD_MASK_MDEFORMVERT) ? @@ -1434,7 +1428,7 @@ void BKE_editmesh_statvis_calc( { BKE_editmesh_color_ensure(em, BM_FACE); statvis_calc_overhang( - em, bmdm ? bmdm->polyNos : NULL, + em, bmdm ? bmdm->emd.polyNos : NULL, statvis->overhang_min / (float)M_PI, statvis->overhang_max / (float)M_PI, statvis->overhang_axis, @@ -1446,7 +1440,7 @@ void BKE_editmesh_statvis_calc( const float scale = 1.0f / mat4_to_scale(em->ob->obmat); BKE_editmesh_color_ensure(em, BM_FACE); statvis_calc_thickness( - em, bmdm ? bmdm->vertexCos : NULL, + em, bmdm ? bmdm->emd.vertexCos : NULL, statvis->thickness_min * scale, statvis->thickness_max * scale, statvis->thickness_samples, @@ -1457,7 +1451,7 @@ void BKE_editmesh_statvis_calc( { BKE_editmesh_color_ensure(em, BM_FACE); statvis_calc_intersect( - em, bmdm ? bmdm->vertexCos : NULL, + em, bmdm ? bmdm->emd.vertexCos : NULL, em->derivedFaceColor); break; } @@ -1469,7 +1463,7 @@ void BKE_editmesh_statvis_calc( emDM_ensurePolyNormals(bmdm); statvis_calc_distort( - em, bmdm ? bmdm->vertexCos : NULL, bmdm ? bmdm->polyNos : NULL, + em, bmdm ? bmdm->emd.vertexCos : NULL, bmdm ? bmdm->emd.polyNos : NULL, statvis->distort_min, statvis->distort_max, em->derivedFaceColor); @@ -1479,7 +1473,7 @@ void BKE_editmesh_statvis_calc( { BKE_editmesh_color_ensure(em, BM_VERT); statvis_calc_sharp( - em, bmdm ? bmdm->vertexCos : NULL, + em, bmdm ? bmdm->emd.vertexCos : NULL, statvis->sharp_min, statvis->sharp_max, /* in this case they are vertex colors */ diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 484537eb35d..24a069a8ed1 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -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; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 8f372a8fa93..f7892e2f08b 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -863,11 +863,16 @@ void modifier_deformVerts(struct ModifierData *md, struct Depsgraph *depsgraph, mti->deformVerts(md, depsgraph, ob, mesh, vertexCos, numVerts, flag); } else { - DerivedMesh *dm = CDDM_from_mesh(mesh); + DerivedMesh *dm = NULL; + if (mesh) { + dm = CDDM_from_mesh(mesh); + } mti->deformVerts_DM(md, depsgraph, ob, dm, vertexCos, numVerts, flag); - dm->release(dm); + if (dm) { + dm->release(dm); + } } } @@ -881,11 +886,16 @@ void modifier_deformMatrices(struct ModifierData *md, struct Depsgraph *depsgrap mti->deformMatrices(md, depsgraph, ob, mesh, vertexCos, defMats, numVerts); } else { - DerivedMesh *dm = CDDM_from_mesh(mesh); + DerivedMesh *dm = NULL; + if (mesh) { + dm = CDDM_from_mesh(mesh); + } mti->deformMatrices_DM(md, depsgraph, ob, dm, vertexCos, defMats, numVerts); - dm->release(dm); + if (dm) { + dm->release(dm); + } } } @@ -899,11 +909,16 @@ void modifier_deformVertsEM(struct ModifierData *md, struct Depsgraph *depsgraph mti->deformVertsEM(md, depsgraph, ob, editData, mesh, vertexCos, numVerts); } else { - DerivedMesh *dm = CDDM_from_mesh(mesh); + DerivedMesh *dm = NULL; + if (mesh) { + dm = CDDM_from_mesh(mesh); + } mti->deformVertsEM_DM(md, depsgraph, ob, editData, dm, vertexCos, numVerts); - dm->release(dm); + if (dm) { + dm->release(dm); + } } } @@ -917,11 +932,16 @@ void modifier_deformMatricesEM(struct ModifierData *md, struct Depsgraph *depsgr mti->deformMatricesEM(md, depsgraph, ob, editData, mesh, vertexCos, defMats, numVerts); } else { - DerivedMesh *dm = CDDM_from_mesh(mesh); + DerivedMesh *dm = NULL; + if (mesh) { + dm = CDDM_from_mesh(mesh); + } mti->deformMatricesEM_DM(md, depsgraph, ob, editData, dm, vertexCos, defMats, numVerts); - dm->release(dm); + if (dm) { + dm->release(dm); + } } } @@ -985,14 +1005,20 @@ void modifier_deformVerts_DM_deprecated(struct ModifierData *md, struct Depsgrap mti->deformVerts_DM(md, depsgraph, ob, dm, vertexCos, numVerts, flag); } else { - struct Mesh mesh; - BKE_mesh_init(&mesh); - - DM_to_mesh(dm, &mesh, ob, CD_MASK_EVERYTHING, false); + /* TODO(sybren): deduplicate all the copies of this code in this file. */ + Mesh *mesh = NULL; + if (dm != NULL) { + mesh = BKE_libblock_alloc_notest(ID_ME); + BKE_mesh_init(mesh); + DM_to_mesh(dm, mesh, ob, CD_MASK_EVERYTHING, false); + } - mti->deformVerts(md, depsgraph, ob, &mesh, vertexCos, numVerts, flag); + mti->deformVerts(md, depsgraph, ob, mesh, vertexCos, numVerts, flag); - BKE_mesh_free(&mesh); + if (mesh != NULL) { + BKE_mesh_free(mesh); + MEM_freeN(mesh); + } } } @@ -1028,14 +1054,19 @@ void modifier_deformVertsEM_DM_deprecated(struct ModifierData *md, struct Depsgr mti->deformVertsEM_DM(md, depsgraph, ob, editData, dm, vertexCos, numVerts); } else { - struct Mesh mesh; - BKE_mesh_init(&mesh); - - DM_to_mesh(dm, &mesh, ob, CD_MASK_EVERYTHING, false); + Mesh *mesh = NULL; + if (dm != NULL) { + mesh = BKE_libblock_alloc_notest(ID_ME); + BKE_mesh_init(mesh); + DM_to_mesh(dm, mesh, ob, CD_MASK_EVERYTHING, false); + } - mti->deformVertsEM(md, depsgraph, ob, editData, &mesh, vertexCos, numVerts); + mti->deformVertsEM(md, depsgraph, ob, editData, mesh, vertexCos, numVerts); - BKE_mesh_free(&mesh); + if (mesh != NULL) { + BKE_mesh_free(mesh); + MEM_freeN(mesh); + } } } @@ -1069,19 +1100,30 @@ struct DerivedMesh *modifier_applyModifier_DM_deprecated(struct ModifierData *md return mti->applyModifier_DM(md, depsgraph, ob, dm, flag); } else { - struct Mesh mesh; - BKE_mesh_init(&mesh); - - DM_to_mesh(dm, &mesh, ob, CD_MASK_EVERYTHING, false); + /* TODO(sybren): deduplicate all the copies of this code in this file. */ + Mesh *mesh = NULL; + if (dm != NULL) { + mesh = BKE_libblock_alloc_notest(ID_ME); + BKE_mesh_init(mesh); + DM_to_mesh(dm, mesh, ob, CD_MASK_EVERYTHING, false); + } - struct Mesh *new_mesh = mti->applyModifier(md, depsgraph, ob, &mesh, flag); + struct Mesh *new_mesh = mti->applyModifier(md, depsgraph, ob, mesh, flag); DerivedMesh *ndm = CDDM_from_mesh(new_mesh); - - if(new_mesh != &mesh) { - BKE_mesh_free(&mesh); - - /* XXX free new_mesh? */ + if(new_mesh != mesh) { + /* Make a DM that doesn't reference new_mesh so we can free the latter. */ + /* TODO(sybren): create CDDM_from_mesh_ex() that creates a copy directly. */ + DerivedMesh *nonref_dm = CDDM_copy(ndm); + ndm->release(ndm); + ndm = nonref_dm; + + BKE_mesh_free(new_mesh); + MEM_freeN(new_mesh); + } + if (mesh != NULL) { + BKE_mesh_free(mesh); + MEM_freeN(mesh); } return ndm; |