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
path: root/source
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@gmail.com>2018-05-25 22:44:33 +0300
committerBrecht Van Lommel <brechtvanlommel@gmail.com>2018-05-26 00:20:20 +0300
commitc9f7a3b32a39aec2c7826f2ffa9939fd705e7237 (patch)
tree009def8c360ace12f15143bddad06f7ebef4ea16 /source
parent768706c6a58fe6b93f3534ca65d1912cbf066e68 (diff)
Fix T55207, fix T55208: hair not positioned correctly after subsurf.
The problem was that the particle system modifier was reading ob->derivedDeform during modifier stack evaluation. Due to the mesh -> DM conversion this was no longer set leading to wrong results. In fact we don't really need the deformed mesh, just the original mesh topology for face/poly index remapping. So the solution is to use that instead.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_particle.h4
-rw-r--r--source/blender/blenkernel/intern/object.c6
-rw-r--r--source/blender/blenkernel/intern/particle.c14
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c4
-rw-r--r--source/blender/blenkernel/intern/particle_system.c8
-rw-r--r--source/blender/blenloader/intern/readfile.c2
-rw-r--r--source/blender/editors/physics/particle_edit.c8
-rw-r--r--source/blender/editors/physics/particle_object.c2
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h2
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c51
10 files changed, 61 insertions, 40 deletions
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index b6a87ae333e..4820f0173bf 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -439,8 +439,8 @@ void psys_particle_on_dm(struct Mesh *mesh_final, int from, int index, int index
/* particle_system.c */
void distribute_particles(struct ParticleSimulationData *sim, int from);
void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa);
-void psys_calc_dmcache(struct Object *ob, struct Mesh *mesh_final, struct Mesh *mesh_deformed, struct ParticleSystem *psys);
-int psys_particle_dm_face_lookup(struct Mesh *mesh_final, struct Mesh *mesh_deformed, int findex, const float fw[4], struct LinkNode **poly_nodes);
+void psys_calc_dmcache(struct Object *ob, struct Mesh *mesh_final, struct Mesh *mesh_original, struct ParticleSystem *psys);
+int psys_particle_dm_face_lookup(struct Mesh *mesh_final, struct Mesh *mesh_original, int findex, const float fw[4], struct LinkNode **poly_nodes);
void reset_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, float dtime, float cfra);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 39e190631ff..b8764f2c29d 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -379,9 +379,9 @@ void BKE_object_free_caches(Object *object)
if (psmd->mesh_final) {
BKE_id_free(NULL, psmd->mesh_final);
psmd->mesh_final = NULL;
- if (psmd->mesh_deformed) {
- BKE_id_free(NULL, psmd->mesh_deformed);
- psmd->mesh_deformed = NULL;
+ if (psmd->mesh_original) {
+ BKE_id_free(NULL, psmd->mesh_original);
+ psmd->mesh_original = NULL;
}
psmd->flag |= eParticleSystemFlag_file_loaded;
update_flag |= OB_RECALC_DATA;
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 26c822f5fef..a42826a1f89 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1295,7 +1295,7 @@ static void psys_origspace_to_w(OrigSpaceFace *osface, int quad, const float w[4
* \return the DM tessface index.
*/
int psys_particle_dm_face_lookup(
- Mesh *mesh_final, Mesh *mesh_deformed,
+ Mesh *mesh_final, Mesh *mesh_original,
int findex_orig, const float fw[4], struct LinkNode **poly_nodes)
{
MFace *mtessface_final;
@@ -1308,7 +1308,7 @@ int psys_particle_dm_face_lookup(
const int *index_mp_to_orig = NULL;
const int totface_final = mesh_final->totface;
- const int totface_deformed = mesh_deformed ? mesh_deformed->totface : totface_final;
+ const int totface_deformed = mesh_original ? mesh_original->totface : totface_final;
if (ELEM(0, totface_final, totface_deformed)) {
return DMCACHE_NOTFOUND;
@@ -1318,8 +1318,8 @@ int psys_particle_dm_face_lookup(
index_mp_to_orig = CustomData_get_layer(&mesh_final->pdata, CD_ORIGINDEX);
BLI_assert(index_mf_to_mpoly);
- if (mesh_deformed) {
- index_mf_to_mpoly_deformed = CustomData_get_layer(&mesh_deformed->fdata, CD_ORIGINDEX);
+ if (mesh_original) {
+ index_mf_to_mpoly_deformed = CustomData_get_layer(&mesh_original->fdata, CD_ORIGINDEX);
}
else {
BLI_assert(mesh_final->runtime.deformed_only);
@@ -1329,8 +1329,8 @@ int psys_particle_dm_face_lookup(
pindex_orig = index_mf_to_mpoly_deformed[findex_orig];
- if (mesh_deformed == NULL) {
- mesh_deformed = mesh_final;
+ if (mesh_original == NULL) {
+ mesh_original = mesh_final;
}
index_mf_to_mpoly_deformed = NULL;
@@ -1349,7 +1349,7 @@ int psys_particle_dm_face_lookup(
return DMCACHE_NOTFOUND;
}
}
- else if (findex_orig >= mesh_deformed->totface) {
+ else if (findex_orig >= mesh_original->totface) {
return DMCACHE_NOTFOUND; /* index not in the original mesh */
}
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
index e85a3f15022..846afd48064 100644
--- a/source/blender/blenkernel/intern/particle_distribute.c
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -847,7 +847,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
/* Simple children */
if (part->childtype != PART_CHILD_FACES) {
BLI_srandom(31415926 + psys->seed + psys->child_seed);
- distribute_simple_children(scene, ob, final_mesh, sim->psmd->mesh_deformed, psys, use_render_params);
+ distribute_simple_children(scene, ob, final_mesh, sim->psmd->mesh_original, psys, use_render_params);
return 0;
}
}
@@ -1233,7 +1233,7 @@ 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_deformed, 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);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 6c454cfa0b1..cba0721ab3f 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -311,7 +311,7 @@ int psys_get_tot_child(Scene *scene, ParticleSystem *psys, const bool use_render
/* Distribution */
/************************************************/
-void psys_calc_dmcache(Object *ob, Mesh *mesh_final, Mesh *mesh_deformed, ParticleSystem *psys)
+void psys_calc_dmcache(Object *ob, Mesh *mesh_final, Mesh *mesh_original, ParticleSystem *psys)
{
/* use for building derived mesh mapping info:
*
@@ -350,7 +350,7 @@ void psys_calc_dmcache(Object *ob, Mesh *mesh_final, Mesh *mesh_deformed, Partic
origindex_poly= NULL;
}
else {
- totelem = mesh_deformed->totface;
+ totelem = mesh_original->totface;
origindex = CustomData_get_layer(&mesh_final->fdata, CD_ORIGINDEX);
/* for face lookups we need the poly origindex too */
@@ -414,7 +414,7 @@ void psys_calc_dmcache(Object *ob, Mesh *mesh_final, Mesh *mesh_deformed, Partic
pa->num_dmcache = DMCACHE_NOTFOUND;
}
else { /* FROM_FACE/FROM_VOLUME */
- pa->num_dmcache = psys_particle_dm_face_lookup(mesh_final, mesh_deformed, pa->num, pa->fuv, nodearray);
+ pa->num_dmcache = psys_particle_dm_face_lookup(mesh_final, mesh_original, pa->num, pa->fuv, nodearray);
}
}
}
@@ -3242,7 +3242,7 @@ static void hair_step(ParticleSimulationData *sim, float cfra, const bool use_re
if (psys->recalc & PSYS_RECALC_RESET) {
/* need this for changing subsurf levels */
- psys_calc_dmcache(sim->ob, sim->psmd->mesh_final, sim->psmd->mesh_deformed, psys);
+ psys_calc_dmcache(sim->ob, sim->psmd->mesh_final, sim->psmd->mesh_original, psys);
if (psys->clmd)
cloth_free_modifier(psys->clmd);
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index e74f82dfb6d..bc4b8daf0d3 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -5230,7 +5230,7 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
psmd->mesh_final = NULL;
- psmd->mesh_deformed = 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/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 5210ff76491..b8a5c138a57 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -2963,7 +2963,7 @@ static void PE_mirror_x(
}
else {
newpa->num_dmcache = psys_particle_dm_face_lookup(
- psmd->mesh_final, psmd->mesh_deformed, newpa->num, newpa->fuv, NULL);
+ psmd->mesh_final, psmd->mesh_original, newpa->num, newpa->fuv, NULL);
}
/* update edit key pointers */
@@ -3557,7 +3557,7 @@ static int brush_add(const bContext *C, PEData *data, short number)
mesh = psmd->mesh_final;
}
else {
- mesh = psmd->mesh_deformed;
+ mesh = psmd->mesh_original;
}
BLI_assert(mesh);
@@ -3591,11 +3591,11 @@ static int brush_add(const bContext *C, PEData *data, short number)
add_pars[n].num = add_pars[n].num_dmcache;
add_pars[n].num_dmcache = DMCACHE_ISCHILD;
}
- else if (mesh == psmd->mesh_deformed) {
+ else if (mesh == psmd->mesh_original) {
/* Final DM is not same topology as orig mesh, we have to map num_dmcache to real final dm. */
add_pars[n].num = add_pars[n].num_dmcache;
add_pars[n].num_dmcache = psys_particle_dm_face_lookup(
- psmd->mesh_final, psmd->mesh_deformed,
+ psmd->mesh_final, psmd->mesh_original,
add_pars[n].num, add_pars[n].fuv, NULL);
}
else {
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index cb7c90a6c3d..55f518a2a8c 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -680,7 +680,7 @@ static bool remap_hair_emitter(
mesh = target_psmd->mesh_final;
}
else {
- mesh = target_psmd->mesh_deformed;
+ mesh = target_psmd->mesh_original;
}
target_mesh = target_psmd->mesh_final;
if (mesh == NULL) {
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 4371172f236..93ab7a035bc 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -739,7 +739,7 @@ typedef struct ParticleSystemModifierData {
struct ParticleSystem *psys;
struct Mesh *mesh_final; /* Final Mesh - its topology may differ from orig mesh. */
- struct Mesh *mesh_deformed; /* Deformed-only Mesh - its topology is same as orig mesh one. */
+ struct Mesh *mesh_original; /* Original mesh that particles are attached to. */
int totdmvert, totdmedge, totdmface;
short flag, pad;
} ParticleSystemModifierData;
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index c2493e6d8f3..72bdcc779ea 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -42,6 +42,7 @@
#include "BKE_cdderivedmesh.h"
+#include "BKE_editmesh.h"
#include "BKE_mesh.h"
#include "BKE_library.h"
#include "BKE_modifier.h"
@@ -55,7 +56,7 @@ static void initData(ModifierData *md)
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
psmd->psys = NULL;
psmd->mesh_final = NULL;
- psmd->mesh_deformed = NULL;
+ psmd->mesh_original = NULL;
psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
}
static void freeData(ModifierData *md)
@@ -65,9 +66,9 @@ static void freeData(ModifierData *md)
if (psmd->mesh_final) {
BKE_id_free(NULL, psmd->mesh_final);
psmd->mesh_final = NULL;
- if (psmd->mesh_deformed) {
- BKE_id_free(NULL, psmd->mesh_deformed);
- psmd->mesh_deformed = NULL;
+ if (psmd->mesh_original) {
+ BKE_id_free(NULL, psmd->mesh_original);
+ psmd->mesh_original = NULL;
}
}
psmd->totdmvert = psmd->totdmedge = psmd->totdmface = 0;
@@ -88,7 +89,7 @@ static void copyData(const ModifierData *md, ModifierData *target)
modifier_copyData_generic(md, target);
tpsmd->mesh_final = NULL;
- tpsmd->mesh_deformed = NULL;
+ tpsmd->mesh_original = NULL;
tpsmd->totdmvert = tpsmd->totdmedge = tpsmd->totdmface = 0;
}
@@ -129,9 +130,9 @@ static void deformVerts(
if (psmd->mesh_final) {
BKE_id_free(NULL, psmd->mesh_final);
psmd->mesh_final = NULL;
- if (psmd->mesh_deformed) {
- BKE_id_free(NULL, psmd->mesh_deformed);
- psmd->mesh_deformed = NULL;
+ if (psmd->mesh_original) {
+ BKE_id_free(NULL, psmd->mesh_original);
+ psmd->mesh_original = NULL;
}
}
else if (psmd->flag & eParticleSystemFlag_file_loaded) {
@@ -156,20 +157,40 @@ static void deformVerts(
BKE_mesh_tessface_ensure(psmd->mesh_final);
if (!psmd->mesh_final->runtime.deformed_only) {
- /* XXX Think we can assume here that if current DM is not only-deformed, ob->deformedOnly has been set.
- * This is awfully weak though. :| */
- if (ctx->object->derivedDeform) {
- DM_to_mesh(ctx->object->derivedDeform, psmd->mesh_deformed, ctx->object, CD_MASK_EVERYTHING, false);
+ /* 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). */
+ Mesh *mesh_original = NULL;
+
+ if (ctx->object->type == OB_MESH) {
+ BMEditMesh *edit_btmesh = BKE_editmesh_from_object(ctx->object);
+
+ if (edit_btmesh) {
+ /* In edit mode get directly from the edit mesh. */
+ psmd->mesh_original = BKE_bmesh_to_mesh_nomain(edit_btmesh->bm, &(struct BMeshToMeshParams){0});
+ }
+ else {
+ /* Otherwise get regular mesh. */
+ mesh_original = ctx->object->data;
+ }
}
- else { /* Can happen in some cases, e.g. when rendering from Edit mode... */
- BKE_id_copy_ex(NULL, &mesh_src->id, (ID **)&psmd->mesh_deformed,
+ else {
+ mesh_original = mesh_src;
+ }
+
+ if (mesh_original) {
+ /* Make a persistent copy of the mesh. We don't actually need
+ * all this data, just some topology for remapping. Could be
+ * optimized once. */
+ BKE_id_copy_ex(NULL, &mesh_original->id, (ID **)&psmd->mesh_original,
LIB_ID_CREATE_NO_MAIN |
LIB_ID_CREATE_NO_USER_REFCOUNT |
LIB_ID_CREATE_NO_DEG_TAG |
LIB_ID_COPY_NO_PREVIEW,
false);
}
- BKE_mesh_tessface_ensure(psmd->mesh_deformed);
+
+ BKE_mesh_tessface_ensure(psmd->mesh_original);
}
if (mesh_src != psmd->mesh_final && mesh_src != mesh) {