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:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h2
-rw-r--r--source/blender/blenkernel/BKE_customdata.h8
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c55
-rw-r--r--source/blender/blenkernel/intern/customdata.c30
-rw-r--r--source/blender/blenkernel/intern/mesh.c5
5 files changed, 83 insertions, 17 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 04251641d9b..236eae29967 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -503,7 +503,7 @@ int DM_release(DerivedMesh *dm);
/** utility function to convert a DerivedMesh to a Mesh
*/
-void DM_to_mesh(DerivedMesh *dm, struct Mesh *me, struct Object *ob, CustomDataMask mask);
+void DM_to_mesh(DerivedMesh *dm, struct Mesh *me, struct Object *ob, CustomDataMask mask, bool take_ownership);
struct BMEditMesh *DM_to_editbmesh(struct DerivedMesh *dm,
struct BMEditMesh *existing, const bool do_tessellate);
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 9028ad09265..6a0cfefb1c2 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -96,6 +96,11 @@ bool CustomData_has_math(const struct CustomData *data);
bool CustomData_has_interp(const struct CustomData *data);
bool CustomData_bmesh_has_free(const struct CustomData *data);
+/**
+ * Checks if any of the customdata layers is referenced.
+ */
+bool CustomData_has_referenced(const struct CustomData *data);
+
/* copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
* another, while not overwriting anything else (e.g. flags). probably only
* implemented for mloopuv/mloopcol, for now.*/
@@ -142,6 +147,9 @@ void CustomData_reset(struct CustomData *data);
*/
void CustomData_free(struct CustomData *data, int totelem);
+/* same as above, but only frees layers which matches the given mask. */
+void CustomData_free_typemask(struct CustomData *data, int totelem, CustomDataMask mask);
+
/* frees all layers with CD_FLAG_TEMPORARY */
void CustomData_free_temporary(struct CustomData *data, int totelem);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 870b020c8de..0bfa3628967 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -531,13 +531,26 @@ MTFace *DM_paint_uvlayer_active_get(DerivedMesh *dm, int mat_nr)
return tf_base;
}
-void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
+void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask, bool take_ownership)
{
/* dm might depend on me, so we need to do everything with a local copy */
Mesh tmp = *me;
int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly;
int did_shapekeys = 0;
-
+ int alloctype = CD_DUPLICATE;
+
+ if (take_ownership && dm->type == DM_TYPE_CDDM && dm->needsFree) {
+ bool has_any_referenced_layers =
+ CustomData_has_referenced(&dm->vertData) ||
+ CustomData_has_referenced(&dm->edgeData) ||
+ CustomData_has_referenced(&dm->loopData) ||
+ CustomData_has_referenced(&dm->faceData) ||
+ CustomData_has_referenced(&dm->polyData);
+ if (!has_any_referenced_layers) {
+ alloctype = CD_ASSIGN;
+ }
+ }
+
CustomData_reset(&tmp.vdata);
CustomData_reset(&tmp.edata);
CustomData_reset(&tmp.fdata);
@@ -552,10 +565,10 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
totpoly = tmp.totpoly = dm->getNumPolys(dm);
tmp.totface = 0;
- CustomData_copy(&dm->vertData, &tmp.vdata, mask, CD_DUPLICATE, totvert);
- CustomData_copy(&dm->edgeData, &tmp.edata, mask, CD_DUPLICATE, totedge);
- CustomData_copy(&dm->loopData, &tmp.ldata, mask, CD_DUPLICATE, totloop);
- CustomData_copy(&dm->polyData, &tmp.pdata, mask, CD_DUPLICATE, totpoly);
+ CustomData_copy(&dm->vertData, &tmp.vdata, mask, alloctype, totvert);
+ CustomData_copy(&dm->edgeData, &tmp.edata, mask, alloctype, totedge);
+ CustomData_copy(&dm->loopData, &tmp.ldata, mask, alloctype, totloop);
+ CustomData_copy(&dm->polyData, &tmp.pdata, mask, alloctype, totpoly);
tmp.cd_flag = dm->cd_flag;
if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) {
@@ -590,13 +603,19 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
/* not all DerivedMeshes store their verts/edges/faces in CustomData, so
* we set them here in case they are missing */
- if (!CustomData_has_layer(&tmp.vdata, CD_MVERT))
- CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN, dm->dupVertArray(dm), totvert);
- if (!CustomData_has_layer(&tmp.edata, CD_MEDGE))
- CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN, dm->dupEdgeArray(dm), totedge);
+ if (!CustomData_has_layer(&tmp.vdata, CD_MVERT)) {
+ CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN,
+ (alloctype == CD_ASSIGN) ? dm->getVertArray(dm) : dm->dupVertArray(dm),
+ totvert);
+ }
+ if (!CustomData_has_layer(&tmp.edata, CD_MEDGE)) {
+ CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN,
+ (alloctype == CD_ASSIGN) ? dm->getEdgeArray(dm) : dm->dupEdgeArray(dm),
+ totedge);
+ }
if (!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) {
- tmp.mloop = dm->dupLoopArray(dm);
- tmp.mpoly = dm->dupPolyArray(dm);
+ tmp.mloop = (alloctype == CD_ASSIGN) ? dm->getLoopArray(dm) : dm->dupLoopArray(dm);
+ tmp.mpoly = (alloctype == CD_ASSIGN) ? dm->getPolyArray(dm) : dm->dupPolyArray(dm);
CustomData_add_layer(&tmp.ldata, CD_MLOOP, CD_ASSIGN, tmp.mloop, tmp.totloop);
CustomData_add_layer(&tmp.pdata, CD_MPOLY, CD_ASSIGN, tmp.mpoly, tmp.totpoly);
@@ -607,7 +626,7 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
if (CustomData_has_layer(&me->ldata, CD_MDISPS)) {
if (totloop == me->totloop) {
MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
- CustomData_add_layer(&tmp.ldata, CD_MDISPS, CD_DUPLICATE, mdisps, totloop);
+ CustomData_add_layer(&tmp.ldata, CD_MDISPS, alloctype, mdisps, totloop);
}
}
@@ -641,6 +660,16 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask)
/* skip the listbase */
MEMCPY_STRUCT_OFS(me, &tmp, id.prev);
+
+ if (take_ownership) {
+ if (alloctype == CD_ASSIGN) {
+ CustomData_free_typemask(&dm->vertData, dm->numVertData, ~mask);
+ CustomData_free_typemask(&dm->edgeData, dm->numEdgeData, ~mask);
+ CustomData_free_typemask(&dm->loopData, dm->numLoopData, ~mask);
+ CustomData_free_typemask(&dm->polyData, dm->numPolyData, ~mask);
+ }
+ dm->release(dm);
+ }
}
void DM_to_meshkey(DerivedMesh *dm, Mesh *me, KeyBlock *kb)
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 65ec6be5a60..999f411cece 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1559,6 +1559,25 @@ void CustomData_free(CustomData *data, int totelem)
CustomData_reset(data);
}
+void CustomData_free_typemask(struct CustomData *data, int totelem, CustomDataMask mask)
+{
+ int i;
+
+ for (i = 0; i < data->totlayer; ++i) {
+ CustomDataLayer *layer = &data->layers[i];
+ if (!(mask & CD_TYPE_AS_MASK(layer->type))) {
+ continue;
+ }
+ customData_free_layer__internal(layer, totelem);
+ }
+
+ if (data->layers)
+ MEM_freeN(data->layers);
+
+ CustomData_external_free(data);
+ CustomData_reset(data);
+}
+
static void customData_update_offsets(CustomData *data)
{
const LayerTypeInfo *typeInfo;
@@ -2876,6 +2895,17 @@ bool CustomData_has_interp(const struct CustomData *data)
return false;
}
+bool CustomData_has_referenced(const struct CustomData *data)
+{
+ int i;
+ for (i = 0; i < data->totlayer; ++i) {
+ if (data->layers[i].flag & CD_FLAG_NOFREE) {
+ return true;
+ }
+ }
+ return false;
+}
+
/* copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
* another, while not overwriting anything else (e.g. flags)*/
void CustomData_data_copy_value(int type, const void *source, void *dest)
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 7757babaca2..809d2137187 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -1501,7 +1501,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use
}
else {
me = BKE_mesh_add(G.main, "Mesh");
- DM_to_mesh(dm, me, ob, CD_MASK_MESH);
+ DM_to_mesh(dm, me, ob, CD_MASK_MESH, false);
}
me->totcol = cu->totcol;
@@ -2256,8 +2256,7 @@ Mesh *BKE_mesh_new_from_object(
dm = mesh_create_derived_view(sce, ob, mask);
tmpmesh = BKE_mesh_add(bmain, "Mesh");
- DM_to_mesh(dm, tmpmesh, ob, mask);
- dm->release(dm);
+ DM_to_mesh(dm, tmpmesh, ob, mask, true);
}
/* BKE_mesh_add/copy gives us a user count we don't need */