From 25619443bba4b9dda8e6194662683e91be99b247 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 10 Jul 2018 11:58:01 +0200 Subject: Ocean Modifier: prevent crashing on 'Apply Modifier' button The 'Apply Modifier' button calls the modifier code on the original object instead of an evaluated copy, which doesn't have an initialised Ocean *. --- source/blender/blenkernel/BKE_ocean.h | 1 + source/blender/blenkernel/intern/ocean.c | 16 ++++++++++++++++ source/blender/modifiers/intern/MOD_ocean.c | 12 ++++++++++++ 3 files changed, 29 insertions(+) diff --git a/source/blender/blenkernel/BKE_ocean.h b/source/blender/blenkernel/BKE_ocean.h index 3bf1af12704..e18a063ff52 100644 --- a/source/blender/blenkernel/BKE_ocean.h +++ b/source/blender/blenkernel/BKE_ocean.h @@ -74,6 +74,7 @@ typedef struct OceanCache { struct Ocean *BKE_ocean_add(void); void BKE_ocean_free_data(struct Ocean *oc); void BKE_ocean_free(struct Ocean *oc); +bool BKE_ocean_ensure(struct OceanModifierData *omd); void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd); void BKE_ocean_init( diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c index b68823626d7..ab0130019b8 100644 --- a/source/blender/blenkernel/intern/ocean.c +++ b/source/blender/blenkernel/intern/ocean.c @@ -836,6 +836,17 @@ struct Ocean *BKE_ocean_add(void) return oc; } +bool BKE_ocean_ensure(struct OceanModifierData *omd) +{ + if (omd->ocean) { + return false; + } + + omd->ocean = BKE_ocean_add(); + BKE_ocean_init_from_modifier(omd->ocean, omd); + return true; +} + void BKE_ocean_init_from_modifier(struct Ocean *ocean, struct OceanModifierData const *omd) { short do_heightfield, do_chop, do_normals, do_jacobian; @@ -1530,6 +1541,11 @@ void BKE_ocean_bake(struct Ocean *UNUSED(o), struct OceanCache *UNUSED(och), /* unused */ (void)update_cb; } + +void BKE_ocean_init_from_modifier(struct Ocean *UNUSED(ocean), struct OceanModifierData const *UNUSED(omd)) +{ +} + #endif /* WITH_OCEANSIM */ void BKE_ocean_free_modifier_cache(struct OceanModifierData *omd) diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index 5aafd9b1877..12845b27166 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -380,6 +380,7 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes OceanModifierData *omd = (OceanModifierData *) md; int cfra_scene = (int)DEG_get_ctime(ctx->depsgraph); Object *ob = ctx->object; + bool allocated_ocean = false; Mesh *result = NULL; OceanResult ocr; @@ -410,6 +411,12 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes BKE_ocean_simulate_cache(omd->oceancache, cfra_scene); } else { + /* omd->ocean is NULL on an original object (in contrast to an evaluated one). + * We can create a new one, but we have to free it as well once we're done. + * This function is only called on an original object when applying the modifier + * using the 'Apply Modifier' button, and thus it is not called frequently for + * simulation. */ + allocated_ocean |= BKE_ocean_ensure(omd); simulate_ocean_modifier(omd); } @@ -503,6 +510,11 @@ static Mesh *doOcean(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mes } } + if (allocated_ocean) { + BKE_ocean_free(omd->ocean); + omd->ocean = NULL; + } + #undef OCEAN_CO return result; -- cgit v1.2.3