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 *.
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user