diff options
-rw-r--r-- | intern/cycles/blender/blender_util.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_mesh.h | 17 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_object.h | 12 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_convert.c | 66 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 4 | ||||
-rw-r--r-- | source/blender/editors/object/object_bake_api.c | 8 | ||||
-rw-r--r-- | source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_main_api.c | 21 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object_api.c | 20 |
9 files changed, 126 insertions, 30 deletions
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 972d7296727..69e55d67532 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -75,11 +75,13 @@ static inline BL::Mesh object_to_mesh(BL::BlendData & /*data*/, * UV are not empty. */ if (mesh.is_editmode() || (mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE)) { - mesh = object.to_mesh(); + BL::Depsgraph depsgraph(PointerRNA_NULL); + mesh = object.to_mesh(false, depsgraph); } } else { - mesh = object.to_mesh(); + BL::Depsgraph depsgraph(PointerRNA_NULL); + mesh = object.to_mesh(false, depsgraph); } #if 0 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); |