Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2019-06-05 13:39:40 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2019-06-13 12:34:01 +0300
commit36faf739a71624b6ca10cec7233779f9eeace0bd (patch)
treead57fbc75b6bce4bdc590384a3fdf4eeb5fdbaf0 /source/blender/editors/physics
parent27537daee1b62aab0fb0d01b89b7d2c044e796cd (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
Diffstat (limited to 'source/blender/editors/physics')
-rw-r--r--source/blender/editors/physics/particle_edit.c108
-rw-r--r--source/blender/editors/physics/particle_object.c23
2 files changed, 74 insertions, 57 deletions
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);