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:
authorSergey Sharybin <sergey.vfx@gmail.com>2015-02-18 22:00:23 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2015-03-13 15:46:55 +0300
commita1a7317f6b098ab6928f33754e57de219877cb64 (patch)
treed14b44056f99d292567fe82c39d6f8d14e6f634d
parent2ef2f085fb743c12d1cabd71d42dd00334de696b (diff)
Add argument to DM_to_mesh() function to take ownership over the DM
The idea is pretty simple: instead of making temporary copy of all the related custom data layers just pass the ownership from the DM to the mesh. This is really handy in cases when you've got DM which you need to convert to Mesh datablock and wouldn't need that DM after conversion anyway. Foe example, render database conversion, exporters and even Modifier Apply will benefit from this option. Reviewers: campbellbarton Differential Revision: https://developer.blender.org/D1127
-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
-rw-r--r--source/blender/collada/collada_utils.cpp3
-rw-r--r--source/blender/editors/object/object_add.c3
-rw-r--r--source/blender/editors/object/object_modifier.c4
8 files changed, 86 insertions, 24 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 */
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index d91689ff496..f15efa89ea6 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -164,8 +164,7 @@ Mesh *bc_get_mesh_copy(Scene *scene, Object *ob, BC_export_mesh_type export_mesh
}
tmpmesh = BKE_mesh_add(G.main, "ColladaMesh"); // name is not important here
- DM_to_mesh(dm, tmpmesh, ob, CD_MASK_MESH);
- dm->release(dm);
+ DM_to_mesh(dm, tmpmesh, ob, CD_MASK_MESH, true);
if (triangulate) {
bc_triangulate_mesh(tmpmesh);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index db7cd991338..99b351561c7 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1700,11 +1700,10 @@ static int convert_exec(bContext *C, wmOperator *op)
dm = mesh_get_derived_final(scene, newob, CD_MASK_MESH);
// dm = mesh_create_derived_no_deform(ob1, NULL); /* this was called original (instead of get_derived). man o man why! (ton) */
- DM_to_mesh(dm, newob->data, newob, CD_MASK_MESH);
+ DM_to_mesh(dm, newob->data, newob, CD_MASK_MESH, true);
/* re-tessellation is called by DM_to_mesh */
- dm->release(dm);
BKE_object_free_modifiers(newob); /* after derivedmesh calls! */
}
else if (ob->type == OB_FONT) {
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index bed85444101..710cf2dbdd2 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -614,9 +614,7 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob,
return 0;
}
- DM_to_mesh(dm, me, ob, CD_MASK_MESH);
-
- dm->release(dm);
+ DM_to_mesh(dm, me, ob, CD_MASK_MESH, true);
if (md->type == eModifierType_Multires)
multires_customdata_delete(me);