diff options
author | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-05-25 22:44:33 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2018-05-26 00:20:20 +0300 |
commit | c9f7a3b32a39aec2c7826f2ffa9939fd705e7237 (patch) | |
tree | 009def8c360ace12f15143bddad06f7ebef4ea16 /source/blender/modifiers | |
parent | 768706c6a58fe6b93f3534ca65d1912cbf066e68 (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/blender/modifiers')
-rw-r--r-- | source/blender/modifiers/intern/MOD_particlesystem.c | 51 |
1 files changed, 36 insertions, 15 deletions
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) { |