diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2019-06-05 13:39:40 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2019-06-13 12:34:01 +0300 |
commit | 36faf739a71624b6ca10cec7233779f9eeace0bd (patch) | |
tree | ad57fbc75b6bce4bdc590384a3fdf4eeb5fdbaf0 | |
parent | 27537daee1b62aab0fb0d01b89b7d2c044e796cd (diff) |
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
-rw-r--r-- | source/blender/blenkernel/BKE_particle.h | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 108 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_distribute.c | 14 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 17 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 2 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_particles.c | 67 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_edit.c | 108 | ||||
-rw-r--r-- | source/blender/editors/physics/particle_object.c | 23 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 8 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_modifier_types.h | 17 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_particle.c | 52 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_explode.c | 2 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_particleinstance.c | 6 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_particlesystem.c | 100 |
15 files changed, 323 insertions, 222 deletions
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 164dbbbf482..ca3a560286f 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -38,6 +38,7 @@ struct ParticleKey; struct ParticleSettings; struct ParticleSystem; struct ParticleSystemModifierData; +struct ParticleSystemModifierDataRuntime; struct BVHTreeRay; struct BVHTreeRayHit; @@ -608,6 +609,13 @@ float psys_get_current_display_percentage(struct ParticleSystem *psys, #define DMCACHE_NOTFOUND -1 #define DMCACHE_ISCHILD -2 +/* **** Particle system modifier helpers. **** */ + +struct Mesh *BKE_particle_modifier_mesh_final_get(struct ParticleSystemModifierData *psmd); +struct Mesh *BKE_particle_modifier_mesh_original_get(struct ParticleSystemModifierData *psmd); +struct ParticleSystemModifierDataRuntime *BKE_particle_modifier_runtime_ensure( + struct ParticleSystemModifierData *psmd); + /* **** Depsgraph evaluation **** */ struct Depsgraph; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 2a66edc8d42..e74b2b0f671 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -497,12 +497,13 @@ void BKE_object_free_caches(Object *object) for (md = object->modifiers.first; md != NULL; md = md->next) { if (md->type == eModifierType_ParticleSystem) { 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; + ParticleSystemModifierDataRuntime *psmd_runtime = BKE_particle_modifier_runtime_ensure(psmd); + if (psmd_runtime->mesh_final) { + BKE_id_free(NULL, psmd_runtime->mesh_final); + psmd_runtime->mesh_final = NULL; + if (psmd_runtime->mesh_original) { + BKE_id_free(NULL, psmd_runtime->mesh_original); + psmd_runtime->mesh_original = NULL; } psmd->flag |= eParticleSystemFlag_file_loaded; update_flag |= ID_RECALC_GEOMETRY; diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 13649eaf096..61ee5685451 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1889,7 +1889,8 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, float vtan[3], float orco[3]) { - if (psmd && psmd->mesh_final) { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); + if (psmd && mesh_final) { if (psmd->psys->part->distr == PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT) { if (vec) { copy_v3_v3(vec, fuv); @@ -1902,7 +1903,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd, } /* we cant use the num_dmcache */ psys_particle_on_dm( - psmd->mesh_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco); + mesh_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco); } else { psys_particle_on_shape(from, index, fuv, vec, nor, utan, vtan, orco); @@ -2253,13 +2254,15 @@ void psys_find_parents(ParticleSimulationData *sim, const bool use_render_params tree = BLI_kdtree_3d_new(totparent); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); + for (p = 0, cpa = sim->psys->child; p < totparent; p++, cpa++) { psys_particle_on_emitter( sim->psmd, from, cpa->num, DMCACHE_ISCHILD, cpa->fuv, cpa->foffset, co, 0, 0, 0, orco); /* Check if particle doesn't exist because of texture influence. * Insert only existing particles into kdtree. */ - get_cpa_texture(sim->psmd->mesh_final, + get_cpa_texture(mesh_final, psys, part, psys->particles + cpa->pa[0], @@ -2427,6 +2430,8 @@ static void psys_thread_create_path(ParticleTask *task, return; } + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(ctx->sim.psmd); + if (ctx->between) { ParticleData *pa = psys->particles + cpa->pa[0]; int w, needupdate; @@ -2531,7 +2536,7 @@ static void psys_thread_create_path(ParticleTask *task, sub_v3_v3v3(off1[w], co, key[w]->co); } - psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); } else { ParticleData *pa = psys->particles + cpa->parent; @@ -2562,7 +2567,7 @@ static void psys_thread_create_path(ParticleTask *task, pa->num_dmcache; /* XXX hack to avoid messed up particle num and subsequent crash (#40733) */ - if (cpa_num > ctx->sim.psmd->mesh_final->totface) { + if (cpa_num > mesh_final->totface) { cpa_num = 0; } cpa_fuv = pa->fuv; @@ -2579,7 +2584,7 @@ static void psys_thread_create_path(ParticleTask *task, 0, orco); - psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); } child_keys->segments = ctx->segments; @@ -2925,19 +2930,21 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re copy_v3_v3(col, &ma->r); } + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); + if ((psys->flag & PSYS_GLOBAL_HAIR) == 0) { if ((psys->part->flag & PART_CHILD_EFFECT) == 0) { - vg_effector = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_EFFECTOR); + vg_effector = psys_cache_vgroup(mesh_final, psys, PSYS_VG_EFFECTOR); } if (!psys->totchild) { - vg_length = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_LENGTH); + vg_length = psys_cache_vgroup(mesh_final, psys, PSYS_VG_LENGTH); } } /* ensure we have tessfaces to be used for mapping */ if (part->from != PART_FROM_VERT) { - BKE_mesh_tessface_ensure(psmd->mesh_final); + BKE_mesh_tessface_ensure(mesh_final); } /*---first main loop: create all actual particles' paths---*/ @@ -2947,7 +2954,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re psys_get_texture(sim, pa, &ptex, PAMAP_LENGTH, 0.f); pa_length = ptex.length * (1.0f - part->randlength * psys_frand(psys, psys->seed + p)); if (vg_length) { - pa_length *= psys_particle_value_from_verts(psmd->mesh_final, part->from, pa, vg_length); + pa_length *= psys_particle_value_from_verts(mesh_final, part->from, pa, vg_length); } } @@ -2965,7 +2972,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re init_particle_interpolation(sim->ob, sim->psys, pa, &pind); /* hairmat is needed for for non-hair particle too so we get proper rotations */ - psys_mat_hair_to_global(sim->ob, psmd->mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, mesh_final, psys->part->from, pa, hairmat); copy_v3_v3(rotmat[0], hairmat[2]); copy_v3_v3(rotmat[1], hairmat[1]); copy_v3_v3(rotmat[2], hairmat[0]); @@ -3023,7 +3030,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re float effector = 1.0f; if (vg_effector) { effector *= psys_particle_value_from_verts( - psmd->mesh_final, psys->part->from, pa, vg_effector); + mesh_final, psys->part->from, pa, vg_effector); } sub_v3_v3v3(vec, (cache[p] + 1)->co, cache[p]->co); @@ -3158,7 +3165,8 @@ static void psys_cache_edit_paths_iter(void *__restrict iter_data_v, init_particle_interpolation(ob, psys, pa, &pind); if (psys) { - psys_mat_hair_to_global(ob, psmd->mesh_final, psys->part->from, pa, hairmat); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); + psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); copy_v3_v3(rotmat[0], hairmat[2]); copy_v3_v3(rotmat[1], hairmat[1]); copy_v3_v3(rotmat[2], hairmat[0]); @@ -4038,8 +4046,9 @@ void psys_get_texture( mul_m4_v3(mtex->object->imat, texvec); } break; - case TEXCO_UV: - if (get_particle_uv(sim->psmd->mesh_final, + case TEXCO_UV: { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); + if (get_particle_uv(mesh_final, pa, 0, pa->fuv, @@ -4050,6 +4059,7 @@ void psys_get_texture( } /* no break, failed to get uv's, so let's try orco's */ ATTR_FALLTHROUGH; + } case TEXCO_ORCO: psys_particle_on_emitter(sim->psmd, sim->psys->part->from, @@ -4323,7 +4333,8 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, } else if (!keyed && !cached && !(psys->flag & PSYS_GLOBAL_HAIR)) { if ((pa->flag & PARS_REKEY) == 0) { - psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, part->from, pa, hairmat); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); + psys_mat_hair_to_global(sim->ob, mesh_final, part->from, pa, hairmat); mul_m4_v3(hairmat, state->co); mul_mat3_m4_v3(hairmat, state->vel); @@ -4405,7 +4416,8 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, 0, par_orco); if (part->type == PART_HAIR) { - psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); + psys_mat_hair_to_global(sim->ob, mesh_final, psys->part->from, pa, hairmat); } else { unit_m4(hairmat); @@ -4437,9 +4449,10 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, 0, par_orco); if (part->type == PART_HAIR) { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); psys_particle_on_emitter( psmd, cpa_from, cpa_num, DMCACHE_ISCHILD, cpa_fuv, pa->foffset, co, 0, 0, 0, orco); - psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim->ob, mesh_final, psys->part->from, pa, hairmat); } else { copy_v3_v3(orco, cpa->fuv); @@ -4450,7 +4463,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, /* get different child parameters from textures & vgroups */ memset(&ctx, 0, sizeof(ParticleThreadContext)); ctx.sim = *sim; - ctx.mesh = psmd->mesh_final; + ctx.mesh = BKE_particle_modifier_mesh_final_get(psmd); ctx.ma = ma; /* TODO: assign vertex groups */ get_child_modifier_parameters(part, &ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex); @@ -4715,14 +4728,16 @@ void psys_get_dupli_texture(ParticleSystem *psys, /* Grid distribution doesn't support UV or emit from vertex mode */ bool is_grid = (part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); + if (cpa) { - if ((part->childtype == PART_CHILD_FACES) && (psmd->mesh_final != NULL)) { - CustomData *mtf_data = &psmd->mesh_final->fdata; + if ((part->childtype == PART_CHILD_FACES) && (mesh_final != NULL)) { + CustomData *mtf_data = &mesh_final->fdata; const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE); mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx); if (mtface && !is_grid) { - mface = CustomData_get(&psmd->mesh_final->fdata, cpa->num, CD_MFACE); + mface = CustomData_get(&mesh_final->fdata, cpa->num, CD_MFACE); mtface += cpa->num; psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv); } @@ -4745,8 +4760,8 @@ void psys_get_dupli_texture(ParticleSystem *psys, } } - if ((part->from == PART_FROM_FACE) && (psmd->mesh_final != NULL) && !is_grid) { - CustomData *mtf_data = &psmd->mesh_final->fdata; + if ((part->from == PART_FROM_FACE) && (mesh_final != NULL) && !is_grid) { + CustomData *mtf_data = &mesh_final->fdata; const int uv_idx = CustomData_get_render_layer(mtf_data, CD_MTFACE); mtface = CustomData_get_layer_n(mtf_data, CD_MTFACE, uv_idx); @@ -4756,14 +4771,14 @@ void psys_get_dupli_texture(ParticleSystem *psys, num = pa->num; } - if (num >= psmd->mesh_final->totface) { + if (num >= mesh_final->totface) { /* happens when simplify is enabled * gives invalid coords but would crash otherwise */ num = DMCACHE_NOTFOUND; } if (mtface && !ELEM(num, DMCACHE_NOTFOUND, DMCACHE_ISCHILD)) { - mface = CustomData_get(&psmd->mesh_final->fdata, num, CD_MFACE); + mface = CustomData_get(&mesh_final->fdata, num, CD_MFACE); mtface += num; psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv); } @@ -4884,8 +4899,10 @@ void psys_apply_hair_lattice(Depsgraph *depsgraph, Scene *scene, Object *ob, Par int p, h; float hairmat[4][4], imat[4][4]; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim.psmd); + for (p = 0; p < psys->totpart; p++, pa++) { - psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim.ob, mesh_final, psys->part->from, pa, hairmat); invert_m4_m4(imat, hairmat); hkey = pa->hair; @@ -4920,3 +4937,40 @@ void BKE_particle_batch_cache_free(ParticleSystem *psys) BKE_particle_batch_cache_free_cb(psys); } } + +/* **** Particle system modifier helpers. **** */ + +Mesh *BKE_particle_modifier_mesh_final_get(ParticleSystemModifierData *psmd) +{ + if (psmd == NULL) { + return NULL; + } + ParticleSystemModifierDataRuntime *runtime = psmd->modifier.runtime; + if (runtime == NULL) { + return NULL; + } + return runtime->mesh_final; +} + +Mesh *BKE_particle_modifier_mesh_original_get(ParticleSystemModifierData *psmd) +{ + if (psmd == NULL) { + return NULL; + } + ParticleSystemModifierDataRuntime *runtime = psmd->modifier.runtime; + if (runtime == NULL) { + return NULL; + } + return runtime->mesh_original; +} + +ParticleSystemModifierDataRuntime *BKE_particle_modifier_runtime_ensure( + ParticleSystemModifierData *psmd) +{ + BLI_assert(psmd != NULL); + if (psmd->modifier.runtime == NULL) { + psmd->modifier.runtime = MEM_callocN(sizeof(ParticleSystemModifierDataRuntime), + "psmd runtime"); + } + return psmd->modifier.runtime; +} diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index 070c3c7a566..7bb2daeab23 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -878,7 +878,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, int from) { Scene *scene = sim->scene; - Mesh *final_mesh = sim->psmd->mesh_final; + Mesh *final_mesh = BKE_particle_modifier_mesh_final_get(sim->psmd); Object *ob = sim->ob; ParticleSystem *psys = sim->psys; ParticleData *pa = 0, *tpars = 0; @@ -926,8 +926,8 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, if (from == PART_FROM_CHILD) { /* Simple children */ if (part->childtype != PART_CHILD_FACES) { - distribute_simple_children( - scene, ob, final_mesh, sim->psmd->mesh_original, psys, use_render_params); + Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(sim->psmd); + distribute_simple_children(scene, ob, final_mesh, mesh_original, psys, use_render_params); return 0; } } @@ -1318,7 +1318,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from) TaskPool *task_pool; ParticleThreadContext ctx; ParticleTask *tasks; - Mesh *final_mesh = sim->psmd->mesh_final; + Mesh *final_mesh = BKE_particle_modifier_mesh_final_get(sim->psmd); int i, totpart, numtasks; /* create a task pool for distribution tasks */ @@ -1346,7 +1346,8 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from) BLI_task_pool_free(task_pool); - psys_calc_dmcache(sim->ob, final_mesh, sim->psmd->mesh_original, sim->psys); + Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(sim->psmd); + psys_calc_dmcache(sim->ob, final_mesh, mesh_original, sim->psys); if (ctx.mesh != final_mesh) { BKE_id_free(NULL, ctx.mesh); @@ -1371,7 +1372,8 @@ void distribute_particles(ParticleSimulationData *sim, int from) int distr_error = 0; if (psmd) { - if (psmd->mesh_final) { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); + if (mesh_final) { distribute_particles_on_dm(sim, from); } else { diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 27722aab2d9..1b0655c6734 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -467,7 +467,7 @@ void psys_thread_context_init(ParticleThreadContext *ctx, ParticleSimulationData { memset(ctx, 0, sizeof(ParticleThreadContext)); ctx->sim = *sim; - ctx->mesh = ctx->sim.psmd->mesh_final; + ctx->mesh = BKE_particle_modifier_mesh_final_get(ctx->sim.psmd); ctx->ma = give_current_material(sim->ob, sim->psys->part->omat); } @@ -3348,6 +3348,7 @@ static void hair_create_input_mesh(ParticleSimulationData *sim, /* make vgroup for pin roots etc.. */ hair_index = 1; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); LOOP_PARTICLES { if (!(pa->flag & PARS_UNEXIST)) { @@ -3358,7 +3359,7 @@ static void hair_create_input_mesh(ParticleSimulationData *sim, pa->hair_index = hair_index; use_hair = psys_hair_use_simulation(pa, max_length); - psys_mat_hair_to_object(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_object(sim->ob, mesh_final, psys->part->from, pa, hairmat); mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat); normalize_m4(root_mat); @@ -3524,7 +3525,9 @@ static void hair_step(ParticleSimulationData *sim, float cfra, const bool use_re if (psys->recalc & ID_RECALC_PSYS_RESET) { /* need this for changing subsurf levels */ - psys_calc_dmcache(sim->ob, sim->psmd->mesh_final, sim->psmd->mesh_original, psys); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); + Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(sim->psmd); + psys_calc_dmcache(sim->ob, mesh_final, mesh_original, psys); if (psys->clmd) { cloth_free_modifier(psys->clmd); @@ -3576,7 +3579,8 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra)) if (pa->totkey) { sub_v3_v3(key->co, root->co); - psys_vec_rot_to_face(sim->psmd->mesh_final, pa, key->co); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd); + psys_vec_rot_to_face(mesh_final, pa, key->co); } key->time = pa->state.time; @@ -4610,12 +4614,13 @@ void particle_system_update(struct Depsgraph *depsgraph, } } - if (!sim.psmd->mesh_final) { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim.psmd); + if (!mesh_final) { return; } if (part->from != PART_FROM_VERT) { - BKE_mesh_tessface_ensure(sim.psmd->mesh_final); + BKE_mesh_tessface_ensure(mesh_final); } /* to verify if we need to restore object afterwards */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ec616907a35..5c2618f61da 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5663,8 +5663,6 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) else if (md->type == eModifierType_ParticleSystem) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; - psmd->mesh_final = NULL; - psmd->mesh_original = NULL; psmd->psys = newdataadr(fd, psmd->psys); psmd->flag &= ~eParticleSystemFlag_psys_updated; psmd->flag |= eParticleSystemFlag_file_loaded; diff --git a/source/blender/draw/intern/draw_cache_impl_particles.c b/source/blender/draw/intern/draw_cache_impl_particles.c index 5b1916447a6..2c66215de6e 100644 --- a/source/blender/draw/intern/draw_cache_impl_particles.c +++ b/source/blender/draw/intern/draw_cache_impl_particles.c @@ -301,14 +301,15 @@ static void particle_calculate_parent_uvs(ParticleSystem *psys, return; } ParticleData *particle = &psys->particles[parent_index]; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); int num = particle->num_dmcache; if (num == DMCACHE_NOTFOUND || num == DMCACHE_ISCHILD) { - if (particle->num < psmd->mesh_final->totface) { + if (particle->num < mesh_final->totface) { num = particle->num; } } if (num != DMCACHE_NOTFOUND && num != DMCACHE_ISCHILD) { - MFace *mface = &psmd->mesh_final->mface[num]; + MFace *mface = &mesh_final->mface[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]); } @@ -330,14 +331,15 @@ static void particle_calculate_parent_mcol(ParticleSystem *psys, return; } ParticleData *particle = &psys->particles[parent_index]; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); int num = particle->num_dmcache; if (num == DMCACHE_NOTFOUND || num == DMCACHE_ISCHILD) { - if (particle->num < psmd->mesh_final->totface) { + if (particle->num < mesh_final->totface) { num = particle->num; } } if (num != DMCACHE_NOTFOUND && num != DMCACHE_ISCHILD) { - MFace *mface = &psmd->mesh_final->mface[num]; + MFace *mface = &mesh_final->mface[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_mcol(mcols[j] + num, mface->v4, particle->fuv, &r_mcol[j]); } @@ -361,8 +363,9 @@ static void particle_interpolate_children_uvs(ParticleSystem *psys, } ChildParticle *particle = &psys->child[child_index]; int num = particle->num; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); if (num != DMCACHE_NOTFOUND) { - MFace *mface = &psmd->mesh_final->mface[num]; + MFace *mface = &mesh_final->mface[num]; for (int j = 0; j < num_uv_layers; j++) { psys_interpolate_uvs(mtfaces[j] + num, mface->v4, particle->fuv, r_uv[j]); } @@ -384,9 +387,10 @@ static void particle_interpolate_children_mcol(ParticleSystem *psys, return; } ChildParticle *particle = &psys->child[child_index]; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); int num = particle->num; if (num != DMCACHE_NOTFOUND) { - MFace *mface = &psmd->mesh_final->mface[num]; + MFace *mface = &mesh_final->mface[num]; for (int j = 0; j < num_col_layers; j++) { psys_interpolate_mcol(mcols[j] + num, mface->v4, particle->fuv, &r_mcol[j]); } @@ -838,15 +842,16 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit int active_col = 0; ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); - if (psmd != NULL && psmd->mesh_final != NULL) { - if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPUV)) { - cache->num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPUV); - active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPUV); + if (psmd != NULL && mesh_final != NULL) { + if (CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) { + cache->num_uv_layers = CustomData_number_of_layers(&mesh_final->ldata, CD_MLOOPUV); + active_uv = CustomData_get_active_layer(&mesh_final->ldata, CD_MLOOPUV); } - if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL)) { - cache->num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPCOL); - active_col = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL); + if (CustomData_has_layer(&mesh_final->ldata, CD_MLOOPCOL)) { + cache->num_col_layers = CustomData_number_of_layers(&mesh_final->ldata, CD_MLOOPCOL); + active_col = CustomData_get_active_layer(&mesh_final->ldata, CD_MLOOPCOL); } } @@ -890,7 +895,7 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit GPU_vertbuf_data_alloc(cache->proc_uv_buf[i], cache->strands_len); GPU_vertbuf_attr_get_raw_data(cache->proc_uv_buf[i], uv_id, &uv_step[i]); - const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i); + const char *name = CustomData_get_layer_name(&mesh_final->ldata, CD_MLOOPUV, i); uint hash = BLI_ghashutil_strhash_p(name); int n = 0; BLI_snprintf(cache->uv_layer_names[i][n++], MAX_LAYER_NAME_LEN, "u%u", hash); @@ -906,13 +911,13 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit GPU_vertbuf_data_alloc(cache->proc_col_buf[i], cache->strands_len); GPU_vertbuf_attr_get_raw_data(cache->proc_col_buf[i], col_id, &col_step[i]); - const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPCOL, i); + const char *name = CustomData_get_layer_name(&mesh_final->ldata, CD_MLOOPCOL, i); uint hash = BLI_ghashutil_strhash_p(name); int n = 0; BLI_snprintf(cache->col_layer_names[i][n++], MAX_LAYER_NAME_LEN, "c%u", hash); /* We only do vcols auto name that are not overridden by uvs */ - if (CustomData_get_named_layer_index(&psmd->mesh_final->ldata, CD_MLOOPUV, name) == -1) { + if (CustomData_get_named_layer_index(&mesh_final->ldata, CD_MLOOPUV, name) == -1) { BLI_snprintf(cache->col_layer_names[i][n++], MAX_LAYER_NAME_LEN, "a%u", hash); } @@ -922,15 +927,15 @@ static void particle_batch_cache_ensure_procedural_strand_data(PTCacheEdit *edit } if (cache->num_uv_layers || cache->num_col_layers) { - BKE_mesh_tessface_ensure(psmd->mesh_final); + BKE_mesh_tessface_ensure(mesh_final); if (cache->num_uv_layers) { for (int j = 0; j < cache->num_uv_layers; j++) { - mtfaces[j] = (MTFace *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MTFACE, j); + mtfaces[j] = (MTFace *)CustomData_get_layer_n(&mesh_final->fdata, CD_MTFACE, j); } } if (cache->num_col_layers) { for (int j = 0; j < cache->num_col_layers; j++) { - mcols[j] = (MCol *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MCOL, j); + mcols[j] = (MCol *)CustomData_get_layer_n(&mesh_final->fdata, CD_MCOL, j); } } } @@ -1143,14 +1148,16 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, float(**parent_uvs)[2] = NULL; MCol **parent_mcol = NULL; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); + if (psmd != NULL) { - if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPUV)) { - num_uv_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPUV); - active_uv = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPUV); + if (CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) { + num_uv_layers = CustomData_number_of_layers(&mesh_final->ldata, CD_MLOOPUV); + active_uv = CustomData_get_active_layer(&mesh_final->ldata, CD_MLOOPUV); } - if (CustomData_has_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL)) { - num_col_layers = CustomData_number_of_layers(&psmd->mesh_final->ldata, CD_MLOOPCOL); - active_col = CustomData_get_active_layer(&psmd->mesh_final->ldata, CD_MLOOPCOL); + if (CustomData_has_layer(&mesh_final->ldata, CD_MLOOPCOL)) { + num_col_layers = CustomData_number_of_layers(&mesh_final->ldata, CD_MLOOPCOL); + active_col = CustomData_get_active_layer(&mesh_final->ldata, CD_MLOOPCOL); } } @@ -1166,7 +1173,7 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, col_id = MEM_mallocN(sizeof(*col_id) * num_col_layers, "Col attr format"); for (int i = 0; i < num_uv_layers; i++) { - const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i); + const char *name = CustomData_get_layer_name(&mesh_final->ldata, CD_MLOOPUV, i); char uuid[32]; BLI_snprintf(uuid, sizeof(uuid), "u%u", BLI_ghashutil_strhash_p(name)); @@ -1178,7 +1185,7 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, } for (int i = 0; i < num_uv_layers; i++) { - const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i); + const char *name = CustomData_get_layer_name(&mesh_final->ldata, CD_MLOOPUV, i); char uuid[32]; BLI_snprintf(uuid, sizeof(uuid), "c%u", BLI_ghashutil_strhash_p(name)); @@ -1197,17 +1204,17 @@ static void particle_batch_cache_ensure_pos_and_seg(PTCacheEdit *edit, GPU_indexbuf_init_ex(&elb, GPU_PRIM_LINE_STRIP, hair_cache->elems_len, hair_cache->point_len); if (num_uv_layers || num_col_layers) { - BKE_mesh_tessface_ensure(psmd->mesh_final); + BKE_mesh_tessface_ensure(mesh_final); if (num_uv_layers) { mtfaces = MEM_mallocN(sizeof(*mtfaces) * num_uv_layers, "Faces UV layers"); for (int i = 0; i < num_uv_layers; i++) { - mtfaces[i] = (MTFace *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MTFACE, i); + mtfaces[i] = (MTFace *)CustomData_get_layer_n(&mesh_final->fdata, CD_MTFACE, i); } } if (num_col_layers) { mcols = MEM_mallocN(sizeof(*mcols) * num_col_layers, "Color layers"); for (int i = 0; i < num_col_layers; i++) { - mcols[i] = (MCol *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MCOL, i); + mcols[i] = (MCol *)CustomData_get_layer_n(&mesh_final->fdata, CD_MCOL, i); } } } diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index dc634865a0a..7506ad37908 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -778,6 +778,7 @@ static void foreach_mouse_hit_key_iter(void *__restrict iter_data_v, } ParticleSystem *psys = edit->psys; ParticleSystemModifierData *psmd_eval = iter_data->edit->psmd_eval; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); ParticleEditSettings *pset = PE_settings(data->scene); const int selected = iter_data->selected; float mat[4][4], imat[4][4]; @@ -793,7 +794,7 @@ static void foreach_mouse_hit_key_iter(void *__restrict iter_data_v, if (key_inside_circle(data, data->rad, KEY_WCO, &mouse_distance)) { if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { psys_mat_hair_to_global( - data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, mat); + data->ob, mesh_final, psys->part->from, psys->particles + iter, mat); invert_m4_m4(imat, mat); } iter_data->func(data, mat, imat, iter, point->totkey - 1, key, mouse_distance); @@ -812,7 +813,7 @@ static void foreach_mouse_hit_key_iter(void *__restrict iter_data_v, if (key_inside_circle(data, data->rad, KEY_WCO, &mouse_distance)) { if (edit->psys && !(edit->psys->flag & PSYS_GLOBAL_HAIR)) { psys_mat_hair_to_global( - data->ob, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, mat); + data->ob, mesh_final, psys->part->from, psys->particles + iter, mat); invert_m4_m4(imat, mat); } iter_data->func(data, mat, imat, iter, k, key, mouse_distance); @@ -927,7 +928,9 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) psmd_eval = edit->psmd_eval; totpart = psys->totpart; - if (!psmd_eval->mesh_final) { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); + + if (!mesh_final) { return; } @@ -937,7 +940,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) LOOP_PARTICLES { key = pa->hair; - psys_mat_hair_to_orco(ob, psmd_eval->mesh_final, psys->part->from, pa, mat); + psys_mat_hair_to_orco(ob, mesh_final, psys->part->from, pa, mat); copy_v3_v3(co, key->co); mul_m4_v3(mat, co); BLI_kdtree_3d_insert(tree, p, co); @@ -953,7 +956,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys) LOOP_PARTICLES { key = pa->hair; - psys_mat_hair_to_orco(ob, psmd_eval->mesh_final, psys->part->from, pa, mat); + psys_mat_hair_to_orco(ob, mesh_final, psys->part->from, pa, mat); copy_v3_v3(co, key->co); mul_m4_v3(mat, co); co[0] = -co[0]; @@ -1084,8 +1087,9 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys) edit = psys->edit; psmd_eval = edit->psmd_eval; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); - if (!psmd_eval->mesh_final) { + if (!mesh_final) { return; } @@ -1102,7 +1106,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys) LOOP_POINTS { if (point->flag & PEP_EDIT_RECALC) { - PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, mesh_final, psys, psys->particles + p, NULL); if (edit->mirror_cache[p] != -1) { edit->points[edit->mirror_cache[p]].flag &= ~PEP_EDIT_RECALC; @@ -1152,8 +1156,8 @@ static void deflect_emitter_iter(void *__restrict iter_data_v, float *vec, *nor, dvec[3], dot, dist_1st = 0.0f; const float dist = iter_data->dist; const float emitterdist = iter_data->emitterdist; - psys_mat_hair_to_object( - object, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, hairmat); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); + psys_mat_hair_to_object(object, mesh_final, psys->part->from, psys->particles + iter, hairmat); LOOP_KEYS { @@ -1217,7 +1221,8 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit) psys = edit->psys; - if (!edit->psmd_eval->mesh_final) { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(edit->psmd_eval); + if (!mesh_final) { return; } @@ -1382,7 +1387,7 @@ void recalc_lengths(PTCacheEdit *edit) void recalc_emitter_field(Depsgraph *UNUSED(depsgraph), Object *UNUSED(ob), ParticleSystem *psys) { PTCacheEdit *edit = psys->edit; - Mesh *mesh = edit->psmd_eval->mesh_final; + Mesh *mesh = BKE_particle_modifier_mesh_final_get(edit->psmd_eval); float *vec, *nor; int i, totface /*, totvert*/; @@ -1489,15 +1494,16 @@ void update_world_cos(Depsgraph *UNUSED(depsgraph), Object *ob, PTCacheEdit *edi KEY_K; float hairmat[4][4]; - if (psys == 0 || psys->edit == 0 || psmd_eval->mesh_final == NULL) { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); + + if (psys == 0 || psys->edit == 0 || mesh_final == NULL) { return; } LOOP_POINTS { if (!(psys->flag & PSYS_GLOBAL_HAIR)) { - psys_mat_hair_to_global( - ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, hairmat); + psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + p, hairmat); } LOOP_KEYS @@ -2269,11 +2275,12 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, const data.is_changed |= PE_deselect_all_visible_ex(edit); } + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); + LOOP_VISIBLE_POINTS { if (edit->psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { - psys_mat_hair_to_global( - ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + p, mat); } if (pset->selectmode == SCE_SELECT_POINT) { @@ -2739,10 +2746,11 @@ static int remove_tagged_particles(Object *ob, ParticleSystem *psys, int mirror) if (mirror) { /* mirror tags */ psmd_eval = edit->psmd_eval; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); LOOP_TAGGED_POINTS { - PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, mesh_final, psys, psys->particles + p, NULL); } } @@ -2831,12 +2839,13 @@ static void remove_tagged_keys(Depsgraph *depsgraph, Object *ob, ParticleSystem ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); ParticleSystemModifierData *psmd_eval = (ParticleSystemModifierData *)modifier_get_evaluated( depsgraph, ob, &psmd->modifier); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); LOOP_POINTS { LOOP_TAGGED_KEYS { - PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL); + PE_mirror_particle(ob, mesh_final, psys, psys->particles + p, NULL); break; } } @@ -3063,6 +3072,8 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) psmd_eval = edit->psmd_eval; totremoved = 0; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); + do { removed = 0; @@ -3071,8 +3082,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) /* insert particles into kd tree */ LOOP_SELECTED_POINTS { - psys_mat_hair_to_object( - ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_object(ob, mesh_final, psys->part->from, psys->particles + p, mat); copy_v3_v3(co, point->keys->co); mul_m4_v3(mat, co); BLI_kdtree_3d_insert(tree, p, co); @@ -3083,8 +3093,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) /* tag particles to be removed */ LOOP_SELECTED_POINTS { - psys_mat_hair_to_object( - ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); + psys_mat_hair_to_object(ob, mesh_final, psys->part->from, psys->particles + p, mat); copy_v3_v3(co, point->keys->co); mul_m4_v3(mat, co); @@ -3347,20 +3356,22 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) } psmd_eval = edit->psmd_eval; - if (!psmd_eval->mesh_final) { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); + Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(psmd_eval); + + if (!mesh_final) { return; } const bool use_dm_final_indices = (psys->part->use_modifier_stack && - !psmd_eval->mesh_final->runtime.deformed_only); + !mesh_final->runtime.deformed_only); /* NOTE: this is not nice to use tessfaces but hard to avoid since pa->num uses tessfaces */ BKE_mesh_tessface_ensure(me); /* NOTE: In case psys uses Mesh tessface indices, we mirror final Mesh itself, not orig mesh. * Avoids an (impossible) mesh -> orig -> mesh tessface indices conversion. */ - mirrorfaces = mesh_get_x_mirror_faces( - ob, NULL, use_dm_final_indices ? psmd_eval->mesh_final : NULL); + mirrorfaces = mesh_get_x_mirror_faces(ob, NULL, use_dm_final_indices ? mesh_final : NULL); if (!edit->mirror_cache) { PE_update_mirror_cache(ob, psys); @@ -3376,7 +3387,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) if (point_is_selected(point)) { if (edit->mirror_cache[p] != -1) { /* already has a mirror, don't need to duplicate */ - PE_mirror_particle(ob, psmd_eval->mesh_final, psys, pa, NULL); + PE_mirror_particle(ob, mesh_final, psys, pa, NULL); continue; } else { @@ -3391,7 +3402,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) } if (newtotpart != psys->totpart) { - MFace *mtessface = use_dm_final_indices ? psmd_eval->mesh_final->mface : me->mface; + MFace *mtessface = use_dm_final_indices ? mesh_final->mface : me->mface; /* allocate new arrays and copy existing */ new_pars = MEM_callocN(newtotpart * sizeof(ParticleData), "ParticleData new"); @@ -3467,7 +3478,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) } else { newpa->num_dmcache = psys_particle_dm_face_lookup( - psmd_eval->mesh_final, psmd_eval->mesh_original, newpa->num, newpa->fuv, NULL); + mesh_final, mesh_original, newpa->num, newpa->fuv, NULL); } /* update edit key pointers */ @@ -3478,7 +3489,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged) } /* map key positions as mirror over x axis */ - PE_mirror_particle(ob, psmd_eval->mesh_final, psys, pa, newpa); + PE_mirror_particle(ob, mesh_final, psys, pa, newpa); newpa++; newpoint++; @@ -4157,19 +4168,18 @@ static void brush_add_count_iter(void *__restrict iter_data_v, 0, 0, 0)) { - if (psys->part->use_modifier_stack && !psmd_eval->mesh_final->runtime.deformed_only) { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); + Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(psmd_eval); + if (psys->part->use_modifier_stack && !mesh_final->runtime.deformed_only) { add_pars[iter].num = add_pars[iter].num_dmcache; add_pars[iter].num_dmcache = DMCACHE_ISCHILD; } - else if (iter_data->mesh == psmd_eval->mesh_original) { + else if (iter_data->mesh == mesh_original) { /* Final DM is not same topology as orig mesh, * we have to map num_dmcache to real final dm. */ add_pars[iter].num = add_pars[iter].num_dmcache; - add_pars[iter].num_dmcache = psys_particle_dm_face_lookup(psmd_eval->mesh_final, - psmd_eval->mesh_original, - add_pars[iter].num, - add_pars[iter].fuv, - NULL); + add_pars[iter].num_dmcache = psys_particle_dm_face_lookup( + mesh_final, mesh_original, add_pars[iter].num, add_pars[iter].fuv, NULL); } else { add_pars[iter].num = add_pars[iter].num_dmcache; @@ -4227,11 +4237,12 @@ static int brush_add(const bContext *C, PEData *data, short number) timestep = psys_get_timestep(&sim); - if (psys->part->use_modifier_stack || psmd_eval->mesh_final->runtime.deformed_only) { - mesh = psmd_eval->mesh_final; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); + if (psys->part->use_modifier_stack || mesh_final->runtime.deformed_only) { + mesh = mesh_final; } else { - mesh = psmd_eval->mesh_original; + mesh = BKE_particle_modifier_mesh_original_get(psmd_eval); } BLI_assert(mesh); @@ -4315,7 +4326,7 @@ static int brush_add(const bContext *C, PEData *data, short number) tree = BLI_kdtree_3d_new(psys->totpart); for (i = 0, pa = psys->particles; i < totpart; i++, pa++) { - psys_particle_on_dm(psmd_eval->mesh_final, + psys_particle_on_dm(mesh_final, psys->part->from, pa->num, pa->num_dmcache, @@ -4372,7 +4383,7 @@ static int brush_add(const bContext *C, PEData *data, short number) int w, maxw; float maxd, totw = 0.0, weight[3]; - psys_particle_on_dm(psmd_eval->mesh_final, + psys_particle_on_dm(mesh_final, psys->part->from, pa->num, pa->num_dmcache, @@ -4450,7 +4461,7 @@ static int brush_add(const bContext *C, PEData *data, short number) } } for (k = 0, hkey = pa->hair; k < pset->totaddkey; k++, hkey++) { - psys_mat_hair_to_global(ob, psmd_eval->mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); invert_m4_m4(imat, hairmat); mul_m4_v3(imat, hkey->co); } @@ -4651,7 +4662,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) } case PE_BRUSH_PUFF: { if (edit->psys) { - data.mesh = psmd_eval->mesh_final; + data.mesh = BKE_particle_modifier_mesh_final_get(psmd_eval); data.mval = mval; data.rad = pe_brush_size_get(scene, brush); data.select = selected; @@ -4708,7 +4719,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr) } case PE_BRUSH_WEIGHT: { if (edit->psys) { - data.mesh = psmd_eval->mesh_final; + data.mesh = BKE_particle_modifier_mesh_final_get(psmd_eval); data.mval = mval; data.rad = pe_brush_size_get(scene, brush); @@ -5082,8 +5093,8 @@ int PE_minmax(Scene *scene, ViewLayer *view_layer, float min[3], float max[3]) LOOP_VISIBLE_POINTS { if (psys) { - psys_mat_hair_to_global( - ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); + psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + p, mat); } LOOP_SELECTED_KEYS @@ -5124,7 +5135,8 @@ void PE_create_particle_edit( } /* no psmd->dm happens in case particle system modifier is not enabled */ - if (!(psys && psmd && psmd_eval->mesh_final) && !cache) { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); + if (!(psys && psmd && mesh_final) && !cache) { return; } diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c index b03ec56c7e4..d85bf72851d 100644 --- a/source/blender/editors/physics/particle_object.c +++ b/source/blender/editors/physics/particle_object.c @@ -620,6 +620,7 @@ static void disconnect_hair(Depsgraph *depsgraph, Scene *scene, Object *ob, Part edit = psys->edit; point = edit ? edit->points : NULL; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); for (i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) { if (point) { @@ -627,7 +628,7 @@ static void disconnect_hair(Depsgraph *depsgraph, Scene *scene, Object *ob, Part point++; } - psys_mat_hair_to_global(ob, psmd_eval->mesh_final, psys->part->from, pa, hairmat); + psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat); for (k = 0, key = pa->hair; k < pa->totkey; k++, key++) { mul_m4_v3(hairmat, key->co); @@ -725,7 +726,8 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, float from_ob_imat[4][4], to_ob_imat[4][4]; float from_imat[4][4], to_imat[4][4]; - if (!target_psmd->mesh_final) { + Mesh *target_mesh_final = BKE_particle_modifier_mesh_final_get(target_psmd); + if (!target_mesh_final) { return false; } if (!psys->part || psys->part->type != PART_HAIR) { @@ -742,14 +744,14 @@ static bool remap_hair_emitter(Depsgraph *depsgraph, invert_m4_m4(from_imat, from_mat); invert_m4_m4(to_imat, to_mat); - if (target_psmd->mesh_final->runtime.deformed_only) { + if (target_mesh_final->runtime.deformed_only) { /* we don't want to mess up target_psmd->dm when converting to global coordinates below */ - mesh = target_psmd->mesh_final; + mesh = target_mesh_final; } else { - mesh = target_psmd->mesh_original; + mesh = BKE_particle_modifier_mesh_original_get(target_psmd); } - target_mesh = target_psmd->mesh_final; + target_mesh = target_mesh_final; if (mesh == NULL) { return false; } @@ -1155,10 +1157,13 @@ static bool copy_particle_systems_to_object(const bContext *C, modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd); psmd->psys = psys; - BKE_id_copy_ex(NULL, &final_mesh->id, (ID **)&psmd->mesh_final, LIB_ID_COPY_LOCALIZE); - BKE_mesh_calc_normals(psmd->mesh_final); - BKE_mesh_tessface_ensure(psmd->mesh_final); + /* TODO(sergey): This should probably be accessing evaluated psmd. */ + ParticleSystemModifierDataRuntime *runtime = BKE_particle_modifier_runtime_ensure(psmd); + BKE_id_copy_ex(NULL, &final_mesh->id, (ID **)&runtime->mesh_final, LIB_ID_COPY_LOCALIZE); + + BKE_mesh_calc_normals(runtime->mesh_final); + BKE_mesh_tessface_ensure(runtime->mesh_final); if (psys_from->edit) { copy_particle_edit(depsgraph, scene, ob_to, psys, psys_from); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 2dad3aef320..b90e89019d7 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2414,8 +2414,8 @@ static void createTransParticleVerts(bContext *C, TransInfo *t) if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { ParticleSystemModifierData *psmd_eval = edit->psmd_eval; - psys_mat_hair_to_global( - ob, psmd_eval->mesh_final, psys->part->from, psys->particles + i, mat); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); + psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + i, mat); } for (k = 0, key = point->keys; k < point->totkey; k++, key++) { @@ -2506,8 +2506,8 @@ void flushTransParticles(TransInfo *t) if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) { ParticleSystemModifierData *psmd_eval = edit->psmd_eval; - psys_mat_hair_to_global( - ob, psmd_eval->mesh_final, psys->part->from, psys->particles + i, mat); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval); + psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + i, mat); invert_m4_m4(imat, mat); for (k = 0, key = point->keys; k < point->totkey; k++, key++) { diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 6a524e03b6e..37980fc5728 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -882,17 +882,24 @@ enum { MOD_MDEF_SURFACE = 1, }; -typedef struct ParticleSystemModifierData { - ModifierData modifier; - - struct ParticleSystem *psys; +/* Is stored in ModifierData.runtime. */ +# +# +typedef struct ParticleSystemModifierDataRuntime { /** Final Mesh - its topology may differ from orig mesh. */ struct Mesh *mesh_final; /** Original mesh that particles are attached to. */ struct Mesh *mesh_original; int totdmvert, totdmedge, totdmface; +} ParticleSystemModifierDataRuntime; + +typedef struct ParticleSystemModifierData { + ModifierData modifier; + + struct ParticleSystem *psys; + void *_pad1; short flag; - char _pad[2]; + char _pad[6]; } ParticleSystemModifierData; typedef enum { diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index c1822b35f28..8112231ed16 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -173,7 +173,8 @@ static void rna_ParticleHairKey_location_object_info(PointerRNA *ptr, for (md = ob->modifiers.first; md; md = md->next) { if (md->type == eModifierType_ParticleSystem) { psmd = (ParticleSystemModifierData *)md; - if (psmd && psmd->mesh_final && psmd->psys) { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); + if (psmd && mesh_final && psmd->psys) { psys = psmd->psys; for (i = 0, pa = psys->particles; i < psys->totpart; i++, pa++) { /* hairkeys are stored sequentially in memory, so we can @@ -208,7 +209,8 @@ static void rna_ParticleHairKey_location_object_get(PointerRNA *ptr, float *valu } else { float hairmat[4][4]; - psys_mat_hair_to_object(ob, psmd->mesh_final, psmd->psys->part->from, pa, hairmat); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); + psys_mat_hair_to_object(ob, mesh_final, psmd->psys->part->from, pa, hairmat); copy_v3_v3(values, hkey->co); mul_m4_v3(hairmat, values); } @@ -238,7 +240,8 @@ static void rna_ParticleHairKey_location_object_set(PointerRNA *ptr, const float float hairmat[4][4]; float imat[4][4]; - psys_mat_hair_to_object(ob, psmd->mesh_final, psmd->psys->part->from, pa, hairmat); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd); + psys_mat_hair_to_object(ob, mesh_final, psmd->psys->part->from, pa, hairmat); invert_m4_m4(imat, hairmat); copy_v3_v3(hkey->co, values); mul_m4_v3(imat, hkey->co); @@ -265,8 +268,8 @@ static void rna_ParticleHairKey_co_object(HairKey *hairkey, } else { float hairmat[4][4]; - psys_mat_hair_to_object( - object, modifier->mesh_final, modifier->psys->part->from, particle, hairmat); + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); + psys_mat_hair_to_object(object, mesh_final, modifier->psys->part->from, particle, hairmat); copy_v3_v3(n_co, hairkey->co); mul_m4_v3(hairmat, n_co); } @@ -290,14 +293,15 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, int num = particle->num_dmcache; int from = modifier->psys->part->from; - if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); + if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) { BKE_report(reports, RPT_ERROR, "Mesh has no UV data"); return; } - BKE_mesh_tessface_ensure(modifier->mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + BKE_mesh_tessface_ensure(mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ if (num == DMCACHE_NOTFOUND) { - if (particle->num < modifier->mesh_final->totface) { + if (particle->num < mesh_final->totface) { num = particle->num; } } @@ -309,8 +313,8 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle, MFace *mface; MTFace *mtface; - mface = modifier->mesh_final->mface; - mtface = modifier->mesh_final->mtface; + mface = mesh_final->mface; + mtface = mesh_final->mtface; if (mface && mtface) { mtface += num; @@ -439,9 +443,10 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys int totvert; int num = -1; - BKE_mesh_tessface_ensure(modifier->mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ - totface = modifier->mesh_final->totface; - totvert = modifier->mesh_final->totvert; + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); + BKE_mesh_tessface_ensure(mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ + totface = mesh_final->totface; + totvert = mesh_final->totvert; /* 1. check that everything is ok & updated */ if (!particlesystem || !totface) { @@ -474,7 +479,7 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys } else if (part->from == PART_FROM_VERT) { if (num != DMCACHE_NOTFOUND && num < totvert) { - MFace *mface = modifier->mesh_final->mface; + MFace *mface = mesh_final->mface; *r_fuv = &particle->fuv; @@ -517,7 +522,7 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys } else if (part->from == PART_FROM_VERT) { if (num != DMCACHE_NOTFOUND && num < totvert) { - MFace *mface = modifier->mesh_final->mface; + MFace *mface = mesh_final->mface; *r_fuv = &parent->fuv; @@ -545,12 +550,13 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, int uv_no, float r_uv[2]) { - if (modifier->mesh_final == NULL) { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); + if (mesh_final == NULL) { BKE_report(reports, RPT_ERROR, "Object was not yet evaluated"); zero_v2(r_uv); return; } - if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) { + if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) { BKE_report(reports, RPT_ERROR, "Mesh has no UV data"); zero_v2(r_uv); return; @@ -567,9 +573,8 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem, zero_v2(r_uv); } else { - MFace *mface = &modifier->mesh_final->mface[num]; - MTFace *mtface = (MTFace *)CustomData_get_layer_n( - &modifier->mesh_final->fdata, CD_MTFACE, uv_no); + MFace *mface = &mesh_final->mface[num]; + MTFace *mtface = (MTFace *)CustomData_get_layer_n(&mesh_final->fdata, CD_MTFACE, uv_no); psys_interpolate_uvs(&mtface[num], mface->v4, *fuv, r_uv); } @@ -584,7 +589,8 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, int vcol_no, float r_mcol[3]) { - if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPCOL)) { + Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier); + if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPCOL)) { BKE_report(reports, RPT_ERROR, "Mesh has no VCol data"); zero_v3(r_mcol); return; @@ -601,8 +607,8 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem, zero_v3(r_mcol); } else { - MFace *mface = &modifier->mesh_final->mface[num]; - MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->mesh_final->fdata, CD_MCOL, vcol_no); + MFace *mface = &mesh_final->mface[num]; + MCol *mc = (MCol *)CustomData_get_layer_n(&mesh_final->fdata, CD_MCOL, vcol_no); MCol mcol; psys_interpolate_mcol(&mc[num * 4], mface->v4, *fuv, &mcol); diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 4ed787810a8..9b1586f4982 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -1125,7 +1125,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes if (psys->part == NULL || psys->particles == NULL) { return mesh; } - if (psmd->mesh_final == NULL) { + if (BKE_particle_modifier_mesh_final_get(psmd) == NULL) { return mesh; } diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index 71913378277..651feb836cc 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -415,7 +415,11 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes ChildParticle *cpa = psys->child + (p - psys->totpart); pa = psys->particles + (between ? cpa->pa[0] : cpa->parent); } - psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, sim.psys->part->from, pa, hairmat); + psys_mat_hair_to_global(sim.ob, + BKE_particle_modifier_mesh_final_get(sim.psmd), + sim.psys->part->from, + pa, + hairmat); copy_m3_m4(mat, hairmat); /* to quaternion */ mat3_to_quat(frame, mat); 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 <stddef.h> +#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, }; |