Revert "Particle system: Move runtime data to runtime field"

This reverts commit 36faf739a7.

Somewhat annoying but this change had some unforeseen consequences,
which lead to an actual bug.

Since this change was not sufficient to get original report fixed
is easier to simply revert for now.

Fixes T65842: Hair disappears when clicking on particle system name
This commit is contained in:
Sergey Sharybin 2019-06-21 11:49:43 +02:00
parent 964e319a39
commit 7070e4c15e
Notes: blender-bot 2023-02-14 08:45:12 +01:00
Referenced by commit cc0819aee1, Fix (unreported) wrong hair vertex colors
Referenced by issue #65842, Hair particles disappear forever from viewport when its name is clicked at the list of particle systems.
15 changed files with 223 additions and 324 deletions

View File

@ -38,7 +38,6 @@ struct ParticleKey;
struct ParticleSettings;
struct ParticleSystem;
struct ParticleSystemModifierData;
struct ParticleSystemModifierDataRuntime;
struct BVHTreeRay;
struct BVHTreeRayHit;
@ -609,13 +608,6 @@ 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;

View File

@ -497,13 +497,12 @@ 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;
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;
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;
}
psmd->flag |= eParticleSystemFlag_file_loaded;
update_flag |= ID_RECALC_GEOMETRY;

View File

@ -1889,8 +1889,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd,
float vtan[3],
float orco[3])
{
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd);
if (psmd && mesh_final) {
if (psmd && 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);
@ -1903,7 +1902,7 @@ void psys_particle_on_emitter(ParticleSystemModifierData *psmd,
}
/* we cant use the num_dmcache */
psys_particle_on_dm(
mesh_final, from, index, index_dmcache, fuv, foffset, vec, nor, utan, vtan, orco);
psmd->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);
@ -2254,15 +2253,13 @@ 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(mesh_final,
get_cpa_texture(sim->psmd->mesh_final,
psys,
part,
psys->particles + cpa->pa[0],
@ -2430,8 +2427,6 @@ 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;
@ -2536,7 +2531,7 @@ static void psys_thread_create_path(ParticleTask *task,
sub_v3_v3v3(off1[w], co, key[w]->co);
}
psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat);
psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat);
}
else {
ParticleData *pa = psys->particles + cpa->parent;
@ -2567,7 +2562,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 > mesh_final->totface) {
if (cpa_num > ctx->sim.psmd->mesh_final->totface) {
cpa_num = 0;
}
cpa_fuv = pa->fuv;
@ -2584,7 +2579,7 @@ static void psys_thread_create_path(ParticleTask *task,
0,
orco);
psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat);
psys_mat_hair_to_global(ob, ctx->sim.psmd->mesh_final, psys->part->from, pa, hairmat);
}
child_keys->segments = ctx->segments;
@ -2930,21 +2925,19 @@ 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(mesh_final, psys, PSYS_VG_EFFECTOR);
vg_effector = psys_cache_vgroup(psmd->mesh_final, psys, PSYS_VG_EFFECTOR);
}
if (!psys->totchild) {
vg_length = psys_cache_vgroup(mesh_final, psys, PSYS_VG_LENGTH);
vg_length = psys_cache_vgroup(psmd->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(mesh_final);
BKE_mesh_tessface_ensure(psmd->mesh_final);
}
/*---first main loop: create all actual particles' paths---*/
@ -2954,7 +2947,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(mesh_final, part->from, pa, vg_length);
pa_length *= psys_particle_value_from_verts(psmd->mesh_final, part->from, pa, vg_length);
}
}
@ -2972,7 +2965,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, mesh_final, psys->part->from, pa, hairmat);
psys_mat_hair_to_global(sim->ob, psmd->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]);
@ -3030,7 +3023,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(
mesh_final, psys->part->from, pa, vg_effector);
psmd->mesh_final, psys->part->from, pa, vg_effector);
}
sub_v3_v3v3(vec, (cache[p] + 1)->co, cache[p]->co);
@ -3165,8 +3158,7 @@ static void psys_cache_edit_paths_iter(void *__restrict iter_data_v,
init_particle_interpolation(ob, psys, pa, &pind);
if (psys) {
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd);
psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat);
psys_mat_hair_to_global(ob, psmd->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]);
@ -4046,9 +4038,8 @@ void psys_get_texture(
mul_m4_v3(mtex->object->imat, texvec);
}
break;
case TEXCO_UV: {
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd);
if (get_particle_uv(mesh_final,
case TEXCO_UV:
if (get_particle_uv(sim->psmd->mesh_final,
pa,
0,
pa->fuv,
@ -4059,7 +4050,6 @@ 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,
@ -4333,8 +4323,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim,
}
else if (!keyed && !cached && !(psys->flag & PSYS_GLOBAL_HAIR)) {
if ((pa->flag & PARS_REKEY) == 0) {
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd);
psys_mat_hair_to_global(sim->ob, mesh_final, part->from, pa, hairmat);
psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, part->from, pa, hairmat);
mul_m4_v3(hairmat, state->co);
mul_mat3_m4_v3(hairmat, state->vel);
@ -4416,8 +4405,7 @@ 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_mat_hair_to_global(sim->ob, mesh_final, psys->part->from, pa, hairmat);
psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat);
}
else {
unit_m4(hairmat);
@ -4449,10 +4437,9 @@ 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, mesh_final, psys->part->from, pa, hairmat);
psys_mat_hair_to_global(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat);
}
else {
copy_v3_v3(orco, cpa->fuv);
@ -4463,7 +4450,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 = BKE_particle_modifier_mesh_final_get(psmd);
ctx.mesh = psmd->mesh_final;
ctx.ma = ma;
/* TODO: assign vertex groups */
get_child_modifier_parameters(part, &ctx, cpa, cpa_from, cpa_num, cpa_fuv, orco, &ptex);
@ -4728,16 +4715,14 @@ 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) && (mesh_final != NULL)) {
CustomData *mtf_data = &mesh_final->fdata;
if ((part->childtype == PART_CHILD_FACES) && (psmd->mesh_final != NULL)) {
CustomData *mtf_data = &psmd->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(&mesh_final->fdata, cpa->num, CD_MFACE);
mface = CustomData_get(&psmd->mesh_final->fdata, cpa->num, CD_MFACE);
mtface += cpa->num;
psys_interpolate_uvs(mtface, mface->v4, cpa->fuv, uv);
}
@ -4760,8 +4745,8 @@ void psys_get_dupli_texture(ParticleSystem *psys,
}
}
if ((part->from == PART_FROM_FACE) && (mesh_final != NULL) && !is_grid) {
CustomData *mtf_data = &mesh_final->fdata;
if ((part->from == PART_FROM_FACE) && (psmd->mesh_final != NULL) && !is_grid) {
CustomData *mtf_data = &psmd->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);
@ -4771,14 +4756,14 @@ void psys_get_dupli_texture(ParticleSystem *psys,
num = pa->num;
}
if (num >= mesh_final->totface) {
if (num >= psmd->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(&mesh_final->fdata, num, CD_MFACE);
mface = CustomData_get(&psmd->mesh_final->fdata, num, CD_MFACE);
mtface += num;
psys_interpolate_uvs(mtface, mface->v4, pa->fuv, uv);
}
@ -4899,10 +4884,8 @@ 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, mesh_final, psys->part->from, pa, hairmat);
psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, psys->part->from, pa, hairmat);
invert_m4_m4(imat, hairmat);
hkey = pa->hair;
@ -4937,40 +4920,3 @@ 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;
}

View File

@ -878,7 +878,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx,
int from)
{
Scene *scene = sim->scene;
Mesh *final_mesh = BKE_particle_modifier_mesh_final_get(sim->psmd);
Mesh *final_mesh = sim->psmd->mesh_final;
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) {
Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(sim->psmd);
distribute_simple_children(scene, ob, final_mesh, mesh_original, psys, use_render_params);
distribute_simple_children(
scene, ob, final_mesh, sim->psmd->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 = BKE_particle_modifier_mesh_final_get(sim->psmd);
Mesh *final_mesh = sim->psmd->mesh_final;
int i, totpart, numtasks;
/* create a task pool for distribution tasks */
@ -1346,8 +1346,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
BLI_task_pool_free(task_pool);
Mesh *mesh_original = BKE_particle_modifier_mesh_original_get(sim->psmd);
psys_calc_dmcache(sim->ob, final_mesh, mesh_original, sim->psys);
psys_calc_dmcache(sim->ob, final_mesh, sim->psmd->mesh_original, sim->psys);
if (ctx.mesh != final_mesh) {
BKE_id_free(NULL, ctx.mesh);
@ -1372,8 +1371,7 @@ void distribute_particles(ParticleSimulationData *sim, int from)
int distr_error = 0;
if (psmd) {
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd);
if (mesh_final) {
if (psmd->mesh_final) {
distribute_particles_on_dm(sim, from);
}
else {

View File

@ -467,7 +467,7 @@ void psys_thread_context_init(ParticleThreadContext *ctx, ParticleSimulationData
{
memset(ctx, 0, sizeof(ParticleThreadContext));
ctx->sim = *sim;
ctx->mesh = BKE_particle_modifier_mesh_final_get(ctx->sim.psmd);
ctx->mesh = ctx->sim.psmd->mesh_final;
ctx->ma = give_current_material(sim->ob, sim->psys->part->omat);
}
@ -3348,7 +3348,6 @@ 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)) {
@ -3359,7 +3358,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, mesh_final, psys->part->from, pa, hairmat);
psys_mat_hair_to_object(sim->ob, sim->psmd->mesh_final, psys->part->from, pa, hairmat);
mul_m4_m4m4(root_mat, sim->ob->obmat, hairmat);
normalize_m4(root_mat);
@ -3525,9 +3524,7 @@ 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 */
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);
psys_calc_dmcache(sim->ob, sim->psmd->mesh_final, sim->psmd->mesh_original, psys);
if (psys->clmd) {
cloth_free_modifier(psys->clmd);
@ -3579,8 +3576,7 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
if (pa->totkey) {
sub_v3_v3(key->co, root->co);
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim->psmd);
psys_vec_rot_to_face(mesh_final, pa, key->co);
psys_vec_rot_to_face(sim->psmd->mesh_final, pa, key->co);
}
key->time = pa->state.time;
@ -4614,13 +4610,12 @@ void particle_system_update(struct Depsgraph *depsgraph,
}
}
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(sim.psmd);
if (!mesh_final) {
if (!sim.psmd->mesh_final) {
return;
}
if (part->from != PART_FROM_VERT) {
BKE_mesh_tessface_ensure(mesh_final);
BKE_mesh_tessface_ensure(sim.psmd->mesh_final);
}
/* to verify if we need to restore object afterwards */

View File

@ -5669,6 +5669,8 @@ 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;

View File

@ -301,15 +301,14 @@ 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 < mesh_final->totface) {
if (particle->num < psmd->mesh_final->totface) {
num = particle->num;
}
}
if (num != DMCACHE_NOTFOUND && num != DMCACHE_ISCHILD) {
MFace *mface = &mesh_final->mface[num];
MFace *mface = &psmd->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]);
}
@ -331,17 +330,16 @@ 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 < mesh_final->totface) {
if (particle->num < psmd->mesh_final->totface) {
num = particle->num;
}
}
if (num != DMCACHE_NOTFOUND && num != DMCACHE_ISCHILD) {
MFace *mface = &mesh_final->mface[num];
MFace *mface = &psmd->mesh_final->mface[num];
for (int j = 0; j < num_col_layers; j++) {
psys_interpolate_mcol(mcols[j] + num * 4, mface->v4, particle->fuv, &r_mcol[j]);
psys_interpolate_mcol(mcols[j] + num, mface->v4, particle->fuv, &r_mcol[j]);
}
}
}
@ -363,9 +361,8 @@ 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 = &mesh_final->mface[num];
MFace *mface = &psmd->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]);
}
@ -387,10 +384,9 @@ 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 = &mesh_final->mface[num];
MFace *mface = &psmd->mesh_final->mface[num];
for (int j = 0; j < num_col_layers; j++) {
psys_interpolate_mcol(mcols[j] + num * 4, mface->v4, particle->fuv, &r_mcol[j]);
}
@ -842,16 +838,15 @@ 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 && 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 (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 (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);
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);
}
}
@ -895,7 +890,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(&mesh_final->ldata, CD_MLOOPUV, i);
const char *name = CustomData_get_layer_name(&psmd->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);
@ -911,13 +906,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(&mesh_final->ldata, CD_MLOOPCOL, i);
const char *name = CustomData_get_layer_name(&psmd->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(&mesh_final->ldata, CD_MLOOPUV, name) == -1) {
if (CustomData_get_named_layer_index(&psmd->mesh_final->ldata, CD_MLOOPUV, name) == -1) {
BLI_snprintf(cache->col_layer_names[i][n++], MAX_LAYER_NAME_LEN, "a%u", hash);
}
@ -927,15 +922,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(mesh_final);
BKE_mesh_tessface_ensure(psmd->mesh_final);
if (cache->num_uv_layers) {
for (int j = 0; j < cache->num_uv_layers; j++) {
mtfaces[j] = (MTFace *)CustomData_get_layer_n(&mesh_final->fdata, CD_MTFACE, j);
mtfaces[j] = (MTFace *)CustomData_get_layer_n(&psmd->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(&mesh_final->fdata, CD_MCOL, j);
mcols[j] = (MCol *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MCOL, j);
}
}
}
@ -1148,16 +1143,14 @@ 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(&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_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_MLOOPCOL)) {
num_col_layers = CustomData_number_of_layers(&mesh_final->ldata, CD_MLOOPCOL);
active_col = CustomData_get_active_layer(&mesh_final->ldata, CD_MLOOPCOL);
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);
}
}
@ -1173,7 +1166,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(&mesh_final->ldata, CD_MLOOPUV, i);
const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i);
char uuid[32];
BLI_snprintf(uuid, sizeof(uuid), "u%u", BLI_ghashutil_strhash_p(name));
@ -1185,7 +1178,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(&mesh_final->ldata, CD_MLOOPUV, i);
const char *name = CustomData_get_layer_name(&psmd->mesh_final->ldata, CD_MLOOPUV, i);
char uuid[32];
BLI_snprintf(uuid, sizeof(uuid), "c%u", BLI_ghashutil_strhash_p(name));
@ -1204,17 +1197,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(mesh_final);
BKE_mesh_tessface_ensure(psmd->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(&mesh_final->fdata, CD_MTFACE, i);
mtfaces[i] = (MTFace *)CustomData_get_layer_n(&psmd->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(&mesh_final->fdata, CD_MCOL, i);
mcols[i] = (MCol *)CustomData_get_layer_n(&psmd->mesh_final->fdata, CD_MCOL, i);
}
}
}

View File

@ -778,7 +778,6 @@ 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];
@ -794,7 +793,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, mesh_final, psys->part->from, psys->particles + iter, mat);
data->ob, psmd_eval->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);
@ -813,7 +812,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, mesh_final, psys->part->from, psys->particles + iter, mat);
data->ob, psmd_eval->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);
@ -928,9 +927,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
psmd_eval = edit->psmd_eval;
totpart = psys->totpart;
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval);
if (!mesh_final) {
if (!psmd_eval->mesh_final) {
return;
}
@ -940,7 +937,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
LOOP_PARTICLES
{
key = pa->hair;
psys_mat_hair_to_orco(ob, mesh_final, psys->part->from, pa, mat);
psys_mat_hair_to_orco(ob, psmd_eval->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);
@ -956,7 +953,7 @@ static void PE_update_mirror_cache(Object *ob, ParticleSystem *psys)
LOOP_PARTICLES
{
key = pa->hair;
psys_mat_hair_to_orco(ob, mesh_final, psys->part->from, pa, mat);
psys_mat_hair_to_orco(ob, psmd_eval->mesh_final, psys->part->from, pa, mat);
copy_v3_v3(co, key->co);
mul_m4_v3(mat, co);
co[0] = -co[0];
@ -1087,9 +1084,8 @@ 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 (!mesh_final) {
if (!psmd_eval->mesh_final) {
return;
}
@ -1106,7 +1102,7 @@ static void PE_apply_mirror(Object *ob, ParticleSystem *psys)
LOOP_POINTS
{
if (point->flag & PEP_EDIT_RECALC) {
PE_mirror_particle(ob, mesh_final, psys, psys->particles + p, NULL);
PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL);
if (edit->mirror_cache[p] != -1) {
edit->points[edit->mirror_cache[p]].flag &= ~PEP_EDIT_RECALC;
@ -1156,8 +1152,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;
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);
psys_mat_hair_to_object(
object, psmd_eval->mesh_final, psys->part->from, psys->particles + iter, hairmat);
LOOP_KEYS
{
@ -1221,8 +1217,7 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
psys = edit->psys;
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(edit->psmd_eval);
if (!mesh_final) {
if (!edit->psmd_eval->mesh_final) {
return;
}
@ -1387,7 +1382,7 @@ void recalc_lengths(PTCacheEdit *edit)
void recalc_emitter_field(Depsgraph *UNUSED(depsgraph), Object *UNUSED(ob), ParticleSystem *psys)
{
PTCacheEdit *edit = psys->edit;
Mesh *mesh = BKE_particle_modifier_mesh_final_get(edit->psmd_eval);
Mesh *mesh = edit->psmd_eval->mesh_final;
float *vec, *nor;
int i, totface /*, totvert*/;
@ -1494,16 +1489,15 @@ void update_world_cos(Depsgraph *UNUSED(depsgraph), Object *ob, PTCacheEdit *edi
KEY_K;
float hairmat[4][4];
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval);
if (psys == 0 || psys->edit == 0 || mesh_final == NULL) {
if (psys == 0 || psys->edit == 0 || psmd_eval->mesh_final == NULL) {
return;
}
LOOP_POINTS
{
if (!(psys->flag & PSYS_GLOBAL_HAIR)) {
psys_mat_hair_to_global(ob, mesh_final, psys->part->from, psys->particles + p, hairmat);
psys_mat_hair_to_global(
ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, hairmat);
}
LOOP_KEYS
@ -2275,12 +2269,11 @@ 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, mesh_final, psys->part->from, psys->particles + p, mat);
psys_mat_hair_to_global(
ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat);
}
if (pset->selectmode == SCE_SELECT_POINT) {
@ -2746,11 +2739,10 @@ 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, mesh_final, psys, psys->particles + p, NULL);
PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL);
}
}
@ -2839,13 +2831,12 @@ 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, mesh_final, psys, psys->particles + p, NULL);
PE_mirror_particle(ob, psmd_eval->mesh_final, psys, psys->particles + p, NULL);
break;
}
}
@ -3072,8 +3063,6 @@ 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;
@ -3082,7 +3071,8 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
/* insert particles into kd tree */
LOOP_SELECTED_POINTS
{
psys_mat_hair_to_object(ob, mesh_final, psys->part->from, psys->particles + p, mat);
psys_mat_hair_to_object(
ob, psmd_eval->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);
@ -3093,7 +3083,8 @@ static int remove_doubles_exec(bContext *C, wmOperator *op)
/* tag particles to be removed */
LOOP_SELECTED_POINTS
{
psys_mat_hair_to_object(ob, mesh_final, psys->part->from, psys->particles + p, mat);
psys_mat_hair_to_object(
ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat);
copy_v3_v3(co, point->keys->co);
mul_m4_v3(mat, co);
@ -3356,22 +3347,20 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
}
psmd_eval = edit->psmd_eval;
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) {
if (!psmd_eval->mesh_final) {
return;
}
const bool use_dm_final_indices = (psys->part->use_modifier_stack &&
!mesh_final->runtime.deformed_only);
!psmd_eval->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 ? mesh_final : NULL);
mirrorfaces = mesh_get_x_mirror_faces(
ob, NULL, use_dm_final_indices ? psmd_eval->mesh_final : NULL);
if (!edit->mirror_cache) {
PE_update_mirror_cache(ob, psys);
@ -3387,7 +3376,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, mesh_final, psys, pa, NULL);
PE_mirror_particle(ob, psmd_eval->mesh_final, psys, pa, NULL);
continue;
}
else {
@ -3402,7 +3391,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
}
if (newtotpart != psys->totpart) {
MFace *mtessface = use_dm_final_indices ? mesh_final->mface : me->mface;
MFace *mtessface = use_dm_final_indices ? psmd_eval->mesh_final->mface : me->mface;
/* allocate new arrays and copy existing */
new_pars = MEM_callocN(newtotpart * sizeof(ParticleData), "ParticleData new");
@ -3478,7 +3467,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
}
else {
newpa->num_dmcache = psys_particle_dm_face_lookup(
mesh_final, mesh_original, newpa->num, newpa->fuv, NULL);
psmd_eval->mesh_final, psmd_eval->mesh_original, newpa->num, newpa->fuv, NULL);
}
/* update edit key pointers */
@ -3489,7 +3478,7 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
}
/* map key positions as mirror over x axis */
PE_mirror_particle(ob, mesh_final, psys, pa, newpa);
PE_mirror_particle(ob, psmd_eval->mesh_final, psys, pa, newpa);
newpa++;
newpoint++;
@ -4168,18 +4157,19 @@ static void brush_add_count_iter(void *__restrict iter_data_v,
0,
0,
0)) {
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) {
if (psys->part->use_modifier_stack && !psmd_eval->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 == mesh_original) {
else if (iter_data->mesh == psmd_eval->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(
mesh_final, mesh_original, add_pars[iter].num, add_pars[iter].fuv, NULL);
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);
}
else {
add_pars[iter].num = add_pars[iter].num_dmcache;
@ -4237,12 +4227,11 @@ static int brush_add(const bContext *C, PEData *data, short number)
timestep = psys_get_timestep(&sim);
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;
if (psys->part->use_modifier_stack || psmd_eval->mesh_final->runtime.deformed_only) {
mesh = psmd_eval->mesh_final;
}
else {
mesh = BKE_particle_modifier_mesh_original_get(psmd_eval);
mesh = psmd_eval->mesh_original;
}
BLI_assert(mesh);
@ -4326,7 +4315,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(mesh_final,
psys_particle_on_dm(psmd_eval->mesh_final,
psys->part->from,
pa->num,
pa->num_dmcache,
@ -4383,7 +4372,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(mesh_final,
psys_particle_on_dm(psmd_eval->mesh_final,
psys->part->from,
pa->num,
pa->num_dmcache,
@ -4461,7 +4450,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, mesh_final, psys->part->from, pa, hairmat);
psys_mat_hair_to_global(ob, psmd_eval->mesh_final, psys->part->from, pa, hairmat);
invert_m4_m4(imat, hairmat);
mul_m4_v3(imat, hkey->co);
}
@ -4662,7 +4651,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
}
case PE_BRUSH_PUFF: {
if (edit->psys) {
data.mesh = BKE_particle_modifier_mesh_final_get(psmd_eval);
data.mesh = psmd_eval->mesh_final;
data.mval = mval;
data.rad = pe_brush_size_get(scene, brush);
data.select = selected;
@ -4719,7 +4708,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
}
case PE_BRUSH_WEIGHT: {
if (edit->psys) {
data.mesh = BKE_particle_modifier_mesh_final_get(psmd_eval);
data.mesh = psmd_eval->mesh_final;
data.mval = mval;
data.rad = pe_brush_size_get(scene, brush);
@ -5093,8 +5082,8 @@ int PE_minmax(Scene *scene, ViewLayer *view_layer, float min[3], float max[3])
LOOP_VISIBLE_POINTS
{
if (psys) {
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);
psys_mat_hair_to_global(
ob, psmd_eval->mesh_final, psys->part->from, psys->particles + p, mat);
}
LOOP_SELECTED_KEYS
@ -5135,8 +5124,7 @@ void PE_create_particle_edit(
}
/* no psmd->dm happens in case particle system modifier is not enabled */
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd_eval);
if (!(psys && psmd && mesh_final) && !cache) {
if (!(psys && psmd && psmd_eval->mesh_final) && !cache) {
return;
}

View File

@ -620,7 +620,6 @@ 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) {
@ -628,7 +627,7 @@ static void disconnect_hair(Depsgraph *depsgraph, Scene *scene, Object *ob, Part
point++;
}
psys_mat_hair_to_global(ob, mesh_final, psys->part->from, pa, hairmat);
psys_mat_hair_to_global(ob, psmd_eval->mesh_final, psys->part->from, pa, hairmat);
for (k = 0, key = pa->hair; k < pa->totkey; k++, key++) {
mul_m4_v3(hairmat, key->co);
@ -726,8 +725,7 @@ 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];
Mesh *target_mesh_final = BKE_particle_modifier_mesh_final_get(target_psmd);
if (!target_mesh_final) {
if (!target_psmd->mesh_final) {
return false;
}
if (!psys->part || psys->part->type != PART_HAIR) {
@ -744,14 +742,14 @@ static bool remap_hair_emitter(Depsgraph *depsgraph,
invert_m4_m4(from_imat, from_mat);
invert_m4_m4(to_imat, to_mat);
if (target_mesh_final->runtime.deformed_only) {
if (target_psmd->mesh_final->runtime.deformed_only) {
/* we don't want to mess up target_psmd->dm when converting to global coordinates below */
mesh = target_mesh_final;
mesh = target_psmd->mesh_final;
}
else {
mesh = BKE_particle_modifier_mesh_original_get(target_psmd);
mesh = target_psmd->mesh_original;
}
target_mesh = target_mesh_final;
target_mesh = target_psmd->mesh_final;
if (mesh == NULL) {
return false;
}
@ -1157,13 +1155,10 @@ 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);
/* 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);
BKE_mesh_calc_normals(psmd->mesh_final);
BKE_mesh_tessface_ensure(psmd->mesh_final);
if (psys_from->edit) {
copy_particle_edit(depsgraph, scene, ob_to, psys, psys_from);

View File

@ -2424,8 +2424,8 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
ParticleSystemModifierData *psmd_eval = edit->psmd_eval;
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);
psys_mat_hair_to_global(
ob, psmd_eval->mesh_final, psys->part->from, psys->particles + i, mat);
}
for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
@ -2516,8 +2516,8 @@ void flushTransParticles(TransInfo *t)
if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
ParticleSystemModifierData *psmd_eval = edit->psmd_eval;
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);
psys_mat_hair_to_global(
ob, psmd_eval->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++) {

View File

@ -882,24 +882,17 @@ enum {
MOD_MDEF_SURFACE = 1,
};
/* Is stored in ModifierData.runtime. */
#
#
typedef struct ParticleSystemModifierDataRuntime {
typedef struct ParticleSystemModifierData {
ModifierData modifier;
struct ParticleSystem *psys;
/** 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[6];
char _pad[2];
} ParticleSystemModifierData;
typedef enum {

View File

@ -173,8 +173,7 @@ 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;
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd);
if (psmd && mesh_final && psmd->psys) {
if (psmd && 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
@ -209,8 +208,7 @@ static void rna_ParticleHairKey_location_object_get(PointerRNA *ptr, float *valu
}
else {
float hairmat[4][4];
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd);
psys_mat_hair_to_object(ob, mesh_final, psmd->psys->part->from, pa, hairmat);
psys_mat_hair_to_object(ob, psmd->mesh_final, psmd->psys->part->from, pa, hairmat);
copy_v3_v3(values, hkey->co);
mul_m4_v3(hairmat, values);
}
@ -240,8 +238,7 @@ static void rna_ParticleHairKey_location_object_set(PointerRNA *ptr, const float
float hairmat[4][4];
float imat[4][4];
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(psmd);
psys_mat_hair_to_object(ob, mesh_final, psmd->psys->part->from, pa, hairmat);
psys_mat_hair_to_object(ob, psmd->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);
@ -268,8 +265,8 @@ static void rna_ParticleHairKey_co_object(HairKey *hairkey,
}
else {
float hairmat[4][4];
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier);
psys_mat_hair_to_object(object, mesh_final, modifier->psys->part->from, particle, hairmat);
psys_mat_hair_to_object(
object, modifier->mesh_final, modifier->psys->part->from, particle, hairmat);
copy_v3_v3(n_co, hairkey->co);
mul_m4_v3(hairmat, n_co);
}
@ -293,15 +290,14 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle,
int num = particle->num_dmcache;
int from = modifier->psys->part->from;
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier);
if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) {
if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) {
BKE_report(reports, RPT_ERROR, "Mesh has no UV data");
return;
}
BKE_mesh_tessface_ensure(mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
BKE_mesh_tessface_ensure(modifier->mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
if (num == DMCACHE_NOTFOUND) {
if (particle->num < mesh_final->totface) {
if (particle->num < modifier->mesh_final->totface) {
num = particle->num;
}
}
@ -313,8 +309,8 @@ static void rna_Particle_uv_on_emitter(ParticleData *particle,
MFace *mface;
MTFace *mtface;
mface = mesh_final->mface;
mtface = mesh_final->mtface;
mface = modifier->mesh_final->mface;
mtface = modifier->mesh_final->mtface;
if (mface && mtface) {
mtface += num;
@ -443,10 +439,9 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys
int totvert;
int num = -1;
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;
BKE_mesh_tessface_ensure(modifier->mesh_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
totface = modifier->mesh_final->totface;
totvert = modifier->mesh_final->totvert;
/* 1. check that everything is ok & updated */
if (!particlesystem || !totface) {
@ -479,7 +474,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 = mesh_final->mface;
MFace *mface = modifier->mesh_final->mface;
*r_fuv = &particle->fuv;
@ -522,7 +517,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 = mesh_final->mface;
MFace *mface = modifier->mesh_final->mface;
*r_fuv = &parent->fuv;
@ -550,13 +545,12 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem,
int uv_no,
float r_uv[2])
{
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier);
if (mesh_final == NULL) {
if (modifier->mesh_final == NULL) {
BKE_report(reports, RPT_ERROR, "Object was not yet evaluated");
zero_v2(r_uv);
return;
}
if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPUV)) {
if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPUV)) {
BKE_report(reports, RPT_ERROR, "Mesh has no UV data");
zero_v2(r_uv);
return;
@ -573,8 +567,9 @@ static void rna_ParticleSystem_uv_on_emitter(ParticleSystem *particlesystem,
zero_v2(r_uv);
}
else {
MFace *mface = &mesh_final->mface[num];
MTFace *mtface = (MTFace *)CustomData_get_layer_n(&mesh_final->fdata, CD_MTFACE, uv_no);
MFace *mface = &modifier->mesh_final->mface[num];
MTFace *mtface = (MTFace *)CustomData_get_layer_n(
&modifier->mesh_final->fdata, CD_MTFACE, uv_no);
psys_interpolate_uvs(&mtface[num], mface->v4, *fuv, r_uv);
}
@ -589,8 +584,7 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem,
int vcol_no,
float r_mcol[3])
{
Mesh *mesh_final = BKE_particle_modifier_mesh_final_get(modifier);
if (!CustomData_has_layer(&mesh_final->ldata, CD_MLOOPCOL)) {
if (!CustomData_has_layer(&modifier->mesh_final->ldata, CD_MLOOPCOL)) {
BKE_report(reports, RPT_ERROR, "Mesh has no VCol data");
zero_v3(r_mcol);
return;
@ -607,8 +601,8 @@ static void rna_ParticleSystem_mcol_on_emitter(ParticleSystem *particlesystem,
zero_v3(r_mcol);
}
else {
MFace *mface = &mesh_final->mface[num];
MCol *mc = (MCol *)CustomData_get_layer_n(&mesh_final->fdata, CD_MCOL, vcol_no);
MFace *mface = &modifier->mesh_final->mface[num];
MCol *mc = (MCol *)CustomData_get_layer_n(&modifier->mesh_final->fdata, CD_MCOL, vcol_no);
MCol mcol;
psys_interpolate_mcol(&mc[num * 4], mface->v4, *fuv, &mcol);

View File

@ -1125,7 +1125,7 @@ static Mesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx, Mes
if (psys->part == NULL || psys->particles == NULL) {
return mesh;
}
if (BKE_particle_modifier_mesh_final_get(psmd) == NULL) {
if (psmd->mesh_final == NULL) {
return mesh;
}

View File

@ -415,11 +415,7 @@ 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,
BKE_particle_modifier_mesh_final_get(sim.psmd),
sim.psys->part->from,
pa,
hairmat);
psys_mat_hair_to_global(sim.ob, sim.psmd->mesh_final, sim.psys->part->from, pa, hairmat);
copy_m3_m4(mat, hairmat);
/* to quaternion */
mat3_to_quat(frame, mat);

View File

@ -23,8 +23,6 @@
#include <stddef.h>
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "DNA_material_types.h"
@ -44,27 +42,24 @@ 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 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);
}
MEM_freeN(runtime_data);
}
static void freeData(ModifierData *md)
{
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
freeRuntimeData(md->runtime);
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;
}
}
psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
/* ED_object_modifier_remove may have freed this first before calling
* modifier_free (which calls this function) */
if (psmd->psys) {
@ -72,6 +67,20 @@ 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)
@ -111,16 +120,14 @@ static void deformVerts(ModifierData *md,
}
}
ParticleSystemModifierDataRuntime *runtime = BKE_particle_modifier_runtime_ensure(psmd);
/* clear old dm */
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;
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;
}
}
else if (psmd->flag & eParticleSystemFlag_file_loaded) {
@ -136,13 +143,13 @@ static void deformVerts(ModifierData *md,
}
/* make new mesh */
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);
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);
BKE_mesh_tessface_ensure(runtime->mesh_final);
BKE_mesh_tessface_ensure(psmd->mesh_final);
if (!runtime->mesh_final->runtime.deformed_only) {
if (!psmd->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). */
@ -153,7 +160,7 @@ static void deformVerts(ModifierData *md,
if (em) {
/* In edit mode get directly from the edit mesh. */
runtime->mesh_original = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL);
psmd->mesh_original = BKE_mesh_from_bmesh_for_eval_nomain(em->bm, NULL);
}
else {
/* Otherwise get regular mesh. */
@ -168,13 +175,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. */
runtime->mesh_original = BKE_mesh_copy_for_eval(mesh_original, false);
psmd->mesh_original = BKE_mesh_copy_for_eval(mesh_original, false);
}
BKE_mesh_tessface_ensure(runtime->mesh_original);
BKE_mesh_tessface_ensure(psmd->mesh_original);
}
if (mesh_src != runtime->mesh_final && mesh_src != mesh) {
if (mesh_src != psmd->mesh_final && mesh_src != mesh) {
BKE_id_free(NULL, mesh_src);
}
@ -182,13 +189,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 && (runtime->mesh_final->totvert != runtime->totdmvert ||
runtime->mesh_final->totedge != runtime->totdmedge ||
runtime->mesh_final->totface != runtime->totdmface)) {
if (had_mesh_final && (psmd->mesh_final->totvert != psmd->totdmvert ||
psmd->mesh_final->totedge != psmd->totdmedge ||
psmd->mesh_final->totface != psmd->totdmface)) {
psys->recalc |= ID_RECALC_PSYS_RESET;
runtime->totdmvert = runtime->mesh_final->totvert;
runtime->totdmedge = runtime->mesh_final->totedge;
runtime->totdmface = runtime->mesh_final->totface;
psmd->totdmvert = psmd->mesh_final->totvert;
psmd->totdmedge = psmd->mesh_final->totedge;
psmd->totdmface = psmd->mesh_final->totface;
}
if (!(ctx->object->transflag & OB_NO_PSYS_UPDATE)) {
@ -238,11 +245,12 @@ ModifierTypeInfo modifierType_ParticleSystem = {
/* structSize */ sizeof(ParticleSystemModifierData),
/* type */ eModifierTypeType_OnlyDeform,
/* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_SupportsMapping |
eModifierTypeFlag_UsesPointCache, /* |
eModifierTypeFlag_UsesPointCache /* |
eModifierTypeFlag_SupportsEditmode |
eModifierTypeFlag_EnableInEditmode */
,
/* copyData */ modifier_copyData_generic,
/* copyData */ copyData,
/* deformVerts */ deformVerts,
/* deformMatrices */ NULL,
@ -260,5 +268,5 @@ ModifierTypeInfo modifierType_ParticleSystem = {
/* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
/* freeRuntimeData */ freeRuntimeData,
/* freeRuntimeData */ NULL,
};