From 36faf739a71624b6ca10cec7233779f9eeace0bd Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 5 Jun 2019 12:39:40 +0200 Subject: Particle system: Move runtime data to runtime field Allows it to be preserved during copy-on-write update when on-geometry related update is needed. This is a required part for T63537, where we need to preserve the entire evaluation data when object is tagged for only RECALC_COPY_ON_WRITE. Reviewers: brecht Reviewed By: brecht Differential Revision: https://developer.blender.org/D5023 --- .../blender/modifiers/intern/MOD_particlesystem.c | 100 ++++++++++----------- 1 file changed, 46 insertions(+), 54 deletions(-) (limited to 'source/blender/modifiers/intern/MOD_particlesystem.c') diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 5d7b380a751..02d477b1bde 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -23,6 +23,8 @@ #include +#include "MEM_guardedalloc.h" + #include "BLI_utildefines.h" #include "DNA_material_types.h" @@ -42,24 +44,27 @@ static void initData(ModifierData *md) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; psmd->psys = NULL; - psmd->mesh_final = NULL; - psmd->mesh_original = NULL; - psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0; } -static void freeData(ModifierData *md) -{ - ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; - if (psmd->mesh_final) { - BKE_id_free(NULL, psmd->mesh_final); - psmd->mesh_final = NULL; - if (psmd->mesh_original) { - BKE_id_free(NULL, psmd->mesh_original); - psmd->mesh_original = NULL; - } +static void freeRuntimeData(void *runtime_data_v) +{ + if (runtime_data_v == NULL) { + return; + } + ParticleSystemModifierDataRuntime *runtime_data = runtime_data_v; + if (runtime_data->mesh_final) { + BKE_id_free(NULL, runtime_data->mesh_final); + } + if (runtime_data->mesh_original) { + BKE_id_free(NULL, runtime_data->mesh_original); } - psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0; + MEM_freeN(runtime_data); +} +static void freeData(ModifierData *md) +{ + ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; + freeRuntimeData(md->runtime); /* ED_object_modifier_remove may have freed this first before calling * modifier_free (which calls this function) */ if (psmd->psys) { @@ -67,20 +72,6 @@ static void freeData(ModifierData *md) } } -static void copyData(const ModifierData *md, ModifierData *target, const int flag) -{ -#if 0 - const ParticleSystemModifierData *psmd = (const ParticleSystemModifierData *)md; -#endif - ParticleSystemModifierData *tpsmd = (ParticleSystemModifierData *)target; - - modifier_copyData_generic(md, target, flag); - - tpsmd->mesh_final = NULL; - tpsmd->mesh_original = NULL; - tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0; -} - static void requiredDataMask(Object *UNUSED(ob), ModifierData *md, CustomData_MeshMasks *r_cddata_masks) @@ -120,14 +111,16 @@ static void deformVerts(ModifierData *md, } } + ParticleSystemModifierDataRuntime *runtime = BKE_particle_modifier_runtime_ensure(psmd); + /* clear old dm */ - bool had_mesh_final = (psmd->mesh_final != NULL); - if (psmd->mesh_final) { - BKE_id_free(NULL, psmd->mesh_final); - psmd->mesh_final = NULL; - if (psmd->mesh_original) { - BKE_id_free(NULL, psmd->mesh_original); - psmd->mesh_original = NULL; + bool had_mesh_final = (runtime->mesh_final != NULL); + if (runtime->mesh_final) { + BKE_id_free(NULL, runtime->mesh_final); + runtime->mesh_final = NULL; + if (runtime->mesh_original) { + BKE_id_free(NULL, runtime->mesh_original); + runtime->mesh_original = NULL; } } else if (psmd->flag & eParticleSystemFlag_file_loaded) { @@ -143,13 +136,13 @@ static void deformVerts(ModifierData *md, } /* make new mesh */ - psmd->mesh_final = BKE_mesh_copy_for_eval(mesh_src, false); - BKE_mesh_apply_vert_coords(psmd->mesh_final, vertexCos); - BKE_mesh_calc_normals(psmd->mesh_final); + runtime->mesh_final = BKE_mesh_copy_for_eval(mesh_src, false); + BKE_mesh_apply_vert_coords(runtime->mesh_final, vertexCos); + BKE_mesh_calc_normals(runtime->mesh_final); - BKE_mesh_tessface_ensure(psmd->mesh_final); + BKE_mesh_tessface_ensure(runtime->mesh_final); - if (!psmd->mesh_final->runtime.deformed_only) { + if (!runtime->mesh_final->runtime.deformed_only) { /* Get the original mesh from the object, this is what the particles * are attached to so in case of non-deform modifiers we need to remap * them to the final mesh (typically subdivision surfaces). */ @@ -160,7 +153,7 @@ static void deformVerts(ModifierData *md, if (em) { /* In edit mode get directly from the edit mesh. */ - psmd->mesh_original = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL); + runtime->mesh_original = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL); } else { /* Otherwise get regular mesh. */ @@ -175,13 +168,13 @@ static void deformVerts(ModifierData *md, /* Make a persistent copy of the mesh. We don't actually need * all this data, just some topology for remapping. Could be * optimized once. */ - psmd->mesh_original = BKE_mesh_copy_for_eval(mesh_original, false); + runtime->mesh_original = BKE_mesh_copy_for_eval(mesh_original, false); } - BKE_mesh_tessface_ensure(psmd->mesh_original); + BKE_mesh_tessface_ensure(runtime->mesh_original); } - if (mesh_src != psmd->mesh_final && mesh_src != mesh) { + if (mesh_src != runtime->mesh_final && mesh_src != mesh) { BKE_id_free(NULL, mesh_src); } @@ -189,13 +182,13 @@ static void deformVerts(ModifierData *md, * This is an unreliable check for the topology check, but allows some * handy configuration like emitting particles from inside particle * instance. */ - if (had_mesh_final && (psmd->mesh_final->totvert != psmd->totdmvert || - psmd->mesh_final->totedge != psmd->totdmedge || - psmd->mesh_final->totface != psmd->totdmface)) { + if (had_mesh_final && (runtime->mesh_final->totvert != runtime->totdmvert || + runtime->mesh_final->totedge != runtime->totdmedge || + runtime->mesh_final->totface != runtime->totdmface)) { psys->recalc |= ID_RECALC_PSYS_RESET; - psmd->totdmvert = psmd->mesh_final->totvert; - psmd->totdmedge = psmd->mesh_final->totedge; - psmd->totdmface = psmd->mesh_final->totface; + runtime->totdmvert = runtime->mesh_final->totvert; + runtime->totdmedge = runtime->mesh_final->totedge; + runtime->totdmface = runtime->mesh_final->totface; } if (!(ctx->object->transflag & OB_NO_PSYS_UPDATE)) { @@ -245,12 +238,11 @@ ModifierTypeInfo modifierType_ParticleSystem = { /* structSize */ sizeof(ParticleSystemModifierData), /* type */ eModifierTypeType_OnlyDeform, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping | - eModifierTypeFlag_UsesPointCache /* | + eModifierTypeFlag_UsesPointCache, /* | eModifierTypeFlag_SupportsEditmode | eModifierTypeFlag_EnableInEditmode */ - , - /* copyData */ copyData, + /* copyData */ modifier_copyData_generic, /* deformVerts */ deformVerts, /* deformMatrices */ NULL, @@ -268,5 +260,5 @@ ModifierTypeInfo modifierType_ParticleSystem = { /* foreachObjectLink */ NULL, /* foreachIDLink */ NULL, /* foreachTexLink */ NULL, - /* freeRuntimeData */ NULL, + /* freeRuntimeData */ freeRuntimeData, }; -- cgit v1.2.3