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
path: root/source
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2019-05-24 15:37:47 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2019-05-27 12:00:42 +0300
commit5dbda33462349a4ac78f08e8ed4ec7922ca7394f (patch)
treeb73b67873cd42dc1a9a927227fd85e9bfb52285e /source
parent07d3d8c2fd75d633a7d6ba6aab47308860af676c (diff)
Depsgraph API: Allow preserving custom data layers
This commit extends dependency graph API with an argument which denotes that all custom data layers are to be preserved. This forces modifier stack re-evaluation with more inclusive mask. Far from ideal, since this might fail in certain configurations with indirectly used objects which might be missing layers needed for the current object evaluation. But this is how it worked for a long time, so should be good enough for until more sophisticated solution is found. In order to use this new behavior two things are to be passed: - Pass keep_all_data_layers=True - Pass a valid dependency graph. The dependency graph is only needed if keep_all_data_layers=True and is NOT to be passed if keep_all_data_layers=False. If keep_all_data_layers=True the dependency graph MUST be passed. Reviewers: mont29, brecht Reviewed By: mont29 Maniphest Tasks: T64994, T64794 Differential Revision: https://developer.blender.org/D4940
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_mesh.h17
-rw-r--r--source/blender/blenkernel/BKE_object.h12
-rw-r--r--source/blender/blenkernel/intern/mesh_convert.c66
-rw-r--r--source/blender/blenkernel/intern/object.c4
-rw-r--r--source/blender/editors/object/object_bake_api.c8
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp2
-rw-r--r--source/blender/makesrna/intern/rna_main_api.c21
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c20
8 files changed, 122 insertions, 28 deletions
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index c410946f438..54fbda1fa31 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -209,11 +209,22 @@ float (*BKE_mesh_vertexCos_get(const struct Mesh *me, int *r_numVerts))[3];
void BKE_mesh_split_faces(struct Mesh *mesh, bool free_loop_normals);
/* Create new mesh from the given object at its current state.
- * The owner of this mesh is unknown, it is up to the caller to decide. */
-struct Mesh *BKE_mesh_new_from_object(struct Object *object);
+ * The owner of this mesh is unknown, it is up to the caller to decide.
+ *
+ * If preserve_all_data_layers is truth then the modifier stack is re-evaluated to ensure it
+ * preserves all possible custom data layers.
+ *
+ * NOTE: Dependency graph argument is required when preserve_all_data_layers is truth, and is
+ * ignored otherwise. */
+struct Mesh *BKE_mesh_new_from_object(struct Depsgraph *depsgraph,
+ struct Object *object,
+ bool preserve_all_data_layers);
/* This is a version of BKE_mesh_new_from_object() which stores mesh in the given main database. */
-struct Mesh *BKE_mesh_new_from_object_to_bmain(struct Main *bmain, struct Object *object);
+struct Mesh *BKE_mesh_new_from_object_to_bmain(struct Main *bmain,
+ struct Depsgraph *depsgraph,
+ struct Object *object,
+ bool preserve_all_data_layers);
struct Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph,
struct Scene *scene,
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index aa4d9696527..df1ac0e4081 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -400,8 +400,16 @@ bool BKE_object_empty_image_data_is_visible_in_view3d(const struct Object *ob,
* The result is owned by the object.
*
* The mesh will be freed when object is re-evaluated or is destroyed. It is possible to force to
- * clear memory sued by this mesh by calling BKE_object_to_mesh_clear(). */
-struct Mesh *BKE_object_to_mesh(struct Object *object);
+ * clear memory sued by this mesh by calling BKE_object_to_mesh_clear().
+ *
+ * If preserve_all_data_layers is truth then the modifier stack is re-evaluated to ensure it
+ * preserves all possible custom data layers.
+ *
+ * NOTE: Dependency graph argument is required when preserve_all_data_layers is truth, and is
+ * ignored otherwise. */
+struct Mesh *BKE_object_to_mesh(struct Depsgraph *depsgraph,
+ struct Object *object,
+ bool preserve_all_data_layers);
void BKE_object_to_mesh_clear(struct Object *object);
diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c
index 461adc823b9..c7ddb8628f9 100644
--- a/source/blender/blenkernel/intern/mesh_convert.c
+++ b/source/blender/blenkernel/intern/mesh_convert.c
@@ -1082,17 +1082,11 @@ static Mesh *mesh_new_from_mball_object(Object *object)
return mesh_result;
}
-static Mesh *mesh_new_from_mesh_object(Object *object)
+static Mesh *mesh_new_from_mesh(Object *object, Mesh *mesh)
{
- Mesh *mesh_input = object->data;
- /* If we are in edit mode, use evaluated mesh from edit structure, matching to what
- * viewport is using for visualization. */
- if (mesh_input->edit_mesh != NULL && mesh_input->edit_mesh->mesh_eval_final) {
- mesh_input = mesh_input->edit_mesh->mesh_eval_final;
- }
Mesh *mesh_result = NULL;
BKE_id_copy_ex(NULL,
- &mesh_input->id,
+ &mesh->id,
(ID **)&mesh_result,
LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT);
/* NOTE: Materials should already be copied. */
@@ -1101,7 +1095,52 @@ static Mesh *mesh_new_from_mesh_object(Object *object)
return mesh_result;
}
-Mesh *BKE_mesh_new_from_object(Object *object)
+static Mesh *mesh_new_from_mesh_object_with_layers(Depsgraph *depsgraph, Object *object)
+{
+ if (DEG_is_original_id(&object->id)) {
+ return mesh_new_from_mesh(object, (Mesh *)object->data);
+ }
+
+ if (depsgraph == NULL) {
+ return NULL;
+ }
+
+ Object object_for_eval = *object;
+ if (object_for_eval.runtime.mesh_orig != NULL) {
+ object_for_eval.data = object_for_eval.runtime.mesh_orig;
+ }
+
+ Scene *scene = DEG_get_evaluated_scene(depsgraph);
+ CustomData_MeshMasks mask = CD_MASK_MESH;
+ Mesh *result;
+
+ if (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER) {
+ result = mesh_create_eval_final_render(depsgraph, scene, &object_for_eval, &mask);
+ }
+ else {
+ result = mesh_create_eval_final_view(depsgraph, scene, &object_for_eval, &mask);
+ }
+
+ return result;
+}
+
+static Mesh *mesh_new_from_mesh_object(Depsgraph *depsgraph,
+ Object *object,
+ bool preserve_all_data_layers)
+{
+ if (preserve_all_data_layers) {
+ return mesh_new_from_mesh_object_with_layers(depsgraph, object);
+ }
+ Mesh *mesh_input = object->data;
+ /* If we are in edit mode, use evaluated mesh from edit structure, matching to what
+ * viewport is using for visualization. */
+ if (mesh_input->edit_mesh != NULL && mesh_input->edit_mesh->mesh_eval_final) {
+ mesh_input = mesh_input->edit_mesh->mesh_eval_final;
+ }
+ return mesh_new_from_mesh(object, mesh_input);
+}
+
+Mesh *BKE_mesh_new_from_object(Depsgraph *depsgraph, Object *object, bool preserve_all_data_layers)
{
Mesh *new_mesh = NULL;
switch (object->type) {
@@ -1114,7 +1153,7 @@ Mesh *BKE_mesh_new_from_object(Object *object)
new_mesh = mesh_new_from_mball_object(object);
break;
case OB_MESH:
- new_mesh = mesh_new_from_mesh_object(object);
+ new_mesh = mesh_new_from_mesh_object(depsgraph, object, preserve_all_data_layers);
break;
default:
/* Object does not have geometry data. */
@@ -1144,9 +1183,12 @@ static int foreach_libblock_make_original_and_usercount_callback(void *user_data
return IDWALK_RET_NOP;
}
-Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain, Object *object)
+Mesh *BKE_mesh_new_from_object_to_bmain(Main *bmain,
+ Depsgraph *depsgraph,
+ Object *object,
+ bool preserve_all_data_layers)
{
- Mesh *mesh = BKE_mesh_new_from_object(object);
+ Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, preserve_all_data_layers);
/* Make sure mesh only points original datablocks, also increase users of materials and other
* possibly referenced data-blocks.
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 85ca9cb26b9..fcb1066b633 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -4499,11 +4499,11 @@ void BKE_object_update_select_id(struct Main *bmain)
}
}
-Mesh *BKE_object_to_mesh(Object *object)
+Mesh *BKE_object_to_mesh(Depsgraph *depsgraph, Object *object, bool preserve_all_data_layers)
{
BKE_object_to_mesh_clear(object);
- Mesh *mesh = BKE_mesh_new_from_object(object);
+ Mesh *mesh = BKE_mesh_new_from_object(depsgraph, object, preserve_all_data_layers);
object->runtime.object_as_temp_mesh = mesh;
return mesh;
}
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index f87342a14ad..2f5a4b44412 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -707,7 +707,7 @@ static size_t initialize_internal_images(BakeImages *bake_images, ReportList *re
/* create new mesh with edit mode changes and modifiers applied */
static Mesh *bake_mesh_new_from_object(Object *object)
{
- Mesh *me = BKE_object_to_mesh(object);
+ Mesh *me = BKE_object_to_mesh(NULL, object, false);
if (me->flag & ME_AUTOSMOOTH) {
BKE_mesh_split_faces(me, true);
@@ -946,7 +946,7 @@ static int bake(Render *re,
md = md_next;
}
- me_cage = BKE_object_to_mesh(ob_low_eval);
+ me_cage = BKE_object_to_mesh(NULL, ob_low_eval, false);
RE_bake_pixels_populate(me_cage, pixel_array_low, num_pixels, &bake_images, uv_layer);
}
@@ -965,7 +965,7 @@ static int bake(Render *re,
highpoly[i].ob_eval = DEG_get_evaluated_object(depsgraph, ob_iter);
highpoly[i].ob_eval->restrictflag &= ~OB_RESTRICT_RENDER;
highpoly[i].ob_eval->base_flag |= (BASE_VISIBLE | BASE_ENABLED_RENDER);
- highpoly[i].me = BKE_object_to_mesh(highpoly[i].ob_eval);
+ highpoly[i].me = BKE_object_to_mesh(NULL, highpoly[i].ob_eval, false);
/* lowpoly to highpoly transformation matrix */
copy_m4_m4(highpoly[i].obmat, highpoly[i].ob->obmat);
@@ -1088,7 +1088,7 @@ static int bake(Render *re,
}
/* Evaluate modifiers again. */
- me_nores = BKE_object_to_mesh(ob_low_eval);
+ me_nores = BKE_object_to_mesh(NULL, ob_low_eval, false);
RE_bake_pixels_populate(me_nores, pixel_array_low, num_pixels, &bake_images, uv_layer);
RE_bake_normal_world_to_tangent(pixel_array_low,
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
index ee13583e67a..e9d81ef479b 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp
@@ -99,7 +99,7 @@ NodeGroup *BlenderFileLoader::Load()
continue;
}
- Mesh *mesh = BKE_object_to_mesh(ob);
+ Mesh *mesh = BKE_object_to_mesh(NULL, ob, false);
if (mesh) {
insertShapeNode(ob, mesh, ++id);
diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c
index bd06cfc1936..aa8de7f23db 100644
--- a/source/blender/makesrna/intern/rna_main_api.c
+++ b/source/blender/makesrna/intern/rna_main_api.c
@@ -332,7 +332,11 @@ static Mesh *rna_Main_meshes_new(Main *bmain, const char *name)
}
/* copied from Mesh_getFromObject and adapted to RNA interface */
-static Mesh *rna_Main_meshes_new_from_object(Main *bmain, ReportList *reports, Object *object)
+static Mesh *rna_Main_meshes_new_from_object(Main *bmain,
+ ReportList *reports,
+ Object *object,
+ bool preserve_all_data_layers,
+ Depsgraph *depsgraph)
{
switch (object->type) {
case OB_FONT:
@@ -346,7 +350,7 @@ static Mesh *rna_Main_meshes_new_from_object(Main *bmain, ReportList *reports, O
return NULL;
}
- return BKE_mesh_new_from_object_to_bmain(bmain, object);
+ return BKE_mesh_new_from_object_to_bmain(bmain, depsgraph, object, preserve_all_data_layers);
}
static Light *rna_Main_lights_new(Main *bmain, const char *name, int type)
@@ -966,6 +970,19 @@ void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_flag(func, FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "object", "Object", "", "Object to create mesh from");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
+ RNA_def_boolean(func,
+ "preserve_all_data_layers",
+ false,
+ "",
+ "Preserve all data layers in the mesh, like UV maps and vertex groups. "
+ "By default Blender only computes the subset of data layers needed for viewport "
+ "display and rendering, for better performance");
+ RNA_def_pointer(
+ func,
+ "depsgraph",
+ "Depsgraph",
+ "Dependency Graph",
+ "Evaluated dependency graph which is required when preserve_all_data_layers is true");
parm = RNA_def_pointer(func,
"mesh",
"Mesh",
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index 7362f6ba610..b5f515277ca 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -375,7 +375,10 @@ static void rna_Object_camera_fit_coords(
}
/* copied from Mesh_getFromObject and adapted to RNA interface */
-static Mesh *rna_Object_to_mesh(Object *object, ReportList *reports)
+static Mesh *rna_Object_to_mesh(Object *object,
+ ReportList *reports,
+ bool preserve_all_data_layers,
+ Depsgraph *depsgraph)
{
/* TODO(sergey): Make it more re-usable function, de-duplicate with
* rna_Main_meshes_new_from_object. */
@@ -391,7 +394,7 @@ static Mesh *rna_Object_to_mesh(Object *object, ReportList *reports)
return NULL;
}
- return BKE_object_to_mesh(object);
+ return BKE_object_to_mesh(depsgraph, object, preserve_all_data_layers);
}
static void rna_Object_to_mesh_clear(Object *object)
@@ -898,6 +901,19 @@ void RNA_api_object(StructRNA *srna)
"data-block. To force free it use to_mesh_clear(). "
"The result is temporary and can not be used by objects from the main database");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
+ RNA_def_boolean(func,
+ "preserve_all_data_layers",
+ false,
+ "",
+ "Preserve all data layers in the mesh, like UV maps and vertex groups. "
+ "By default Blender only computes the subset of data layers needed for viewport "
+ "display and rendering, for better performance");
+ RNA_def_pointer(
+ func,
+ "depsgraph",
+ "Depsgraph",
+ "Dependency Graph",
+ "Evaluated dependency graph which is required when preserve_all_data_layers is true");
parm = RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object");
RNA_def_function_return(func, parm);