From 2b723abea02c868d94623f4dd9e9b6775cb3aaab Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 30 Apr 2021 16:22:51 +1000 Subject: Object: improve on fix for Object.to_mesh() crash T86871 While fa7ddd0f43ea15dd19d81e7808de2bfe8cfc89ee fixed the reported issue, the possibility of reusing runtime data during curve-to-mesh conversion remained. Instead of treating the bounding-box as a special case, clear all run-time data for temporary objects. Ref D11026 Reviewed By: sergey --- source/blender/blenkernel/BKE_object.h | 1 + source/blender/blenkernel/intern/mesh_convert.c | 29 ++++++++++++++----------- source/blender/blenkernel/intern/object.c | 11 ++++++++++ 3 files changed, 28 insertions(+), 13 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index 9fe286df36d..c5eae586e9c 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -374,6 +374,7 @@ struct MovieClip *BKE_object_movieclip_get(struct Scene *scene, void BKE_object_runtime_reset(struct Object *object); void BKE_object_runtime_reset_on_copy(struct Object *object, const int flag); +void BKE_object_runtime_free(struct Object *object); void BKE_object_batch_cache_dirty_tag(struct Object *ob); diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c index 1ec3b6a1cbf..e03a5f03fb5 100644 --- a/source/blender/blenkernel/intern/mesh_convert.c +++ b/source/blender/blenkernel/intern/mesh_convert.c @@ -1027,11 +1027,15 @@ static Object *object_for_curve_to_mesh_create(Object *object) * * Note that there are extra fields in there like bevel and path, but those are not needed during * conversion, so they are not copied to save unnecessary allocations. */ - if (object->runtime.curve_cache != NULL) { + if (temp_object->runtime.curve_cache == NULL) { temp_object->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for curve types"); + } + + if (object->runtime.curve_cache != NULL) { BKE_displist_copy(&temp_object->runtime.curve_cache->disp, &object->runtime.curve_cache->disp); } + /* Constructive modifiers will use mesh to store result. */ if (object->runtime.data_eval != NULL) { BKE_id_copy_ex( @@ -1059,15 +1063,17 @@ static Object *object_for_curve_to_mesh_create(Object *object) static void curve_to_mesh_eval_ensure(Object *object) { - if (object->runtime.curve_cache == NULL) { - object->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); - } Curve *curve = (Curve *)object->data; Curve remapped_curve = *curve; Object remapped_object = *object; - remapped_object.runtime.bb = NULL; + BKE_object_runtime_reset(&remapped_object); + remapped_object.data = &remapped_curve; + if (remapped_object.runtime.curve_cache == NULL) { + remapped_object.runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); + } + /* Clear all modifiers for the bevel object. * * This is because they can not be reliably evaluated for an original object (at least because @@ -1078,8 +1084,8 @@ static void curve_to_mesh_eval_ensure(Object *object) Object bevel_object = {{NULL}}; if (remapped_curve.bevobj != NULL) { bevel_object = *remapped_curve.bevobj; - bevel_object.runtime.bb = NULL; BLI_listbase_clear(&bevel_object.modifiers); + BKE_object_runtime_reset(&bevel_object); remapped_curve.bevobj = &bevel_object; } @@ -1087,8 +1093,8 @@ static void curve_to_mesh_eval_ensure(Object *object) Object taper_object = {{NULL}}; if (remapped_curve.taperobj != NULL) { taper_object = *remapped_curve.taperobj; - taper_object.runtime.bb = NULL; BLI_listbase_clear(&taper_object.modifiers); + BKE_object_runtime_reset(&taper_object); remapped_curve.taperobj = &taper_object; } @@ -1110,12 +1116,9 @@ static void curve_to_mesh_eval_ensure(Object *object) BKE_object_eval_assign_data(&remapped_object, &mesh_eval->id, true); } - MEM_SAFE_FREE(remapped_object.runtime.bb); - MEM_SAFE_FREE(taper_object.runtime.bb); - MEM_SAFE_FREE(bevel_object.runtime.bb); - - BKE_object_free_curve_cache(&bevel_object); - BKE_object_free_curve_cache(&taper_object); + BKE_object_runtime_free(&remapped_object); + BKE_object_runtime_free(&taper_object); + BKE_object_runtime_free(&taper_object); } static Mesh *mesh_new_from_curve_type_object(Object *object) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 82d99e980a4..912bd5a4d69 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -5113,6 +5113,17 @@ void BKE_object_runtime_reset_on_copy(Object *object, const int UNUSED(flag)) runtime->geometry_set_eval = NULL; } +/** + * The function frees memory used by the runtime data, but not the runtime field itself. + * + * The caller is expected to run #BKE_object_runtime_reset if the struct will be used again. + */ +void BKE_object_runtime_free(Object *object) +{ + /* Currently this is all that's needed. */ + BKE_object_free_derived_caches(object); +} + /** * Find an associated armature object. */ -- cgit v1.2.3