Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@stuvel.eu>2018-04-19 12:03:58 +0300
committerSybren A. Stüvel <sybren@stuvel.eu>2018-05-01 19:02:17 +0300
commit7efc75c7092b085fe3f5ef2dcab3669d466dfadc (patch)
treecbadfa4924b27dbd39f362025538857983c60d6d /source/blender/blenkernel
parentbe4df85919b42cb2cf8a01c904a8552c5c173944 (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.h8
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c26
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c114
-rw-r--r--source/blender/blenkernel/intern/mesh.c77
-rw-r--r--source/blender/blenkernel/intern/modifier.c102
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;