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:
authorLukas Tönne <lukas.toenne@gmail.com>2015-01-15 20:15:52 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2015-01-20 11:30:11 +0300
commit0666de06f3119ff1640f1eb66833cd4feb669209 (patch)
tree39591d1ac9085ef4c22a5c06028e09444ad9332d /source
parent2a41d8ebdca623f03b022b15b9ad50a4ce2c611b (diff)
Fix for particle system copy: This has to make sure the ORIGSPACE data
layer is available. Otherwise particle mapping to the new mesh cannot work with subdivided and constructively-modified meshes.
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_particle.h3
-rw-r--r--source/blender/blenkernel/intern/particle.c36
-rw-r--r--source/blender/editors/physics/particle_object.c54
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c32
4 files changed, 74 insertions, 51 deletions
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index bdf3a36370e..a5f12bb9a3c 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -39,6 +39,8 @@
#include "DNA_particle_types.h"
#include "DNA_object_types.h"
+#include "BKE_customdata.h"
+
struct ParticleSystemModifierData;
struct ParticleSystem;
struct ParticleKey;
@@ -312,6 +314,7 @@ void psys_interpolate_mcol(const struct MCol *mcol, int quad, const float w[4],
void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int time);
+CustomDataMask psys_emitter_customdata_mask(struct ParticleSystem *psys);
void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache,
float fuv[4], float foffset, float vec[3], float nor[3],
float utan[3], float vtan[3], float orco[3], float ornor[3]);
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 72cb69aa183..b146a40db63 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1646,6 +1646,42 @@ static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index),
/************************************************/
/* Particles on emitter */
/************************************************/
+
+CustomDataMask psys_emitter_customdata_mask(ParticleSystem *psys)
+{
+ CustomDataMask dataMask = 0;
+ MTex *mtex;
+ int i;
+
+ if (!psys->part)
+ return 0;
+
+ for (i = 0; i < MAX_MTEX; i++) {
+ mtex = psys->part->mtex[i];
+ if (mtex && mtex->mapto && (mtex->texco & TEXCO_UV))
+ dataMask |= CD_MASK_MTFACE;
+ }
+
+ if (psys->part->tanfac != 0.0f)
+ dataMask |= CD_MASK_MTFACE;
+
+ /* ask for vertexgroups if we need them */
+ for (i = 0; i < PSYS_TOT_VG; i++) {
+ if (psys->vgroup[i]) {
+ dataMask |= CD_MASK_MDEFORMVERT;
+ break;
+ }
+ }
+
+ /* particles only need this if they are after a non deform modifier, and
+ * the modifier stack will only create them in that case. */
+ dataMask |= CD_MASK_ORIGSPACE_MLOOP | CD_MASK_ORIGINDEX;
+
+ dataMask |= CD_MASK_ORCO;
+
+ return dataMask;
+}
+
void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache,
float fuv[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3],
float orco[3], float ornor[3])
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 33bf2b815f9..c7794d3092e 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -651,9 +651,10 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
}
static bool remap_hair_emitter(Scene *scene, Object *UNUSED(ob), ParticleSystem *psys,
- Object *target_ob, DerivedMesh *target_dm, ParticleSystem *target_psys, PTCacheEdit *target_edit,
+ Object *target_ob, ParticleSystem *target_psys, PTCacheEdit *target_edit,
bool from_world_space, bool to_world_space)
{
+ ParticleSystemModifierData *target_psmd = psys_get_modifier(target_ob, target_psys);
ParticleData *pa, *tpa;
PTCacheEditPoint *edit_point;
PTCacheEditKey *ekey;
@@ -661,22 +662,28 @@ static bool remap_hair_emitter(Scene *scene, Object *UNUSED(ob), ParticleSystem
MFace *mface = NULL, *mf;
MEdge *medge = NULL, *me;
MVert *mvert;
- DerivedMesh *dm;
+ DerivedMesh *dm, *target_dm;
int numverts;
int i, k;
- if (!psys->part || psys->part->type != PART_HAIR || !target_psys->part || target_psys->part->type != PART_HAIR)
+ if (!target_psmd->dm)
+ return false;
+ if (!psys->part || psys->part->type != PART_HAIR)
+ return false;
+ if (!target_psys->part || target_psys->part->type != PART_HAIR)
return false;
edit_point = target_edit ? target_edit->points : NULL;
- if (target_dm->deformedOnly) {
- /* we don't want to mess up target_dm when converting to global coordinates below */
- dm = target_dm;
+ if (target_psmd->dm->deformedOnly) {
+ /* we don't want to mess up target_psmd->dm when converting to global coordinates below */
+ dm = target_psmd->dm;
}
else {
+ /* warning: this rebuilds target_psmd->dm! */
dm = mesh_get_derived_deform(scene, target_ob, CD_MASK_BAREMESH);
}
+ target_dm = target_psmd->dm;
/* don't modify the original vertices */
dm = CDDM_copy(dm);
@@ -738,7 +745,7 @@ static bool remap_hair_emitter(Scene *scene, Object *UNUSED(ob), ParticleSystem
tpa->foffset = 0.0f;
tpa->num = nearest.index;
- tpa->num_dmcache = psys_particle_dm_face_lookup(target_ob, dm, tpa->num, tpa->fuv, NULL);
+ tpa->num_dmcache = psys_particle_dm_face_lookup(target_ob, target_dm, tpa->num, tpa->fuv, NULL);
}
else {
me = &medge[nearest.index];
@@ -812,19 +819,14 @@ static bool remap_hair_emitter(Scene *scene, Object *UNUSED(ob), ParticleSystem
static bool connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
{
- ParticleSystemModifierData *psmd;
const bool from_global = psys->flag & PSYS_GLOBAL_HAIR;
const bool to_global = false;
if (!psys)
return false;
- psmd = psys_get_modifier(ob, psys);
- if (!psmd->dm)
- return false;
-
psys->flag &= ~PSYS_GLOBAL_HAIR;
- return remap_hair_emitter(scene, ob, psys, ob, psmd->dm, psys, psys->edit, from_global, to_global);
+ return remap_hair_emitter(scene, ob, psys, ob, psys, psys->edit, from_global, to_global);
}
static int connect_hair_exec(bContext *C, wmOperator *op)
@@ -937,6 +939,7 @@ static bool copy_particle_systems_to_object(Scene *scene, Object *ob_from, Objec
ModifierData *md, *md_next;
ParticleSystem *psys, *psys_from;
DerivedMesh *final_dm;
+ CustomDataMask cdmask;
int i;
if (ob_to->type != OB_MESH)
@@ -960,16 +963,18 @@ static bool copy_particle_systems_to_object(Scene *scene, Object *ob_from, Objec
}
BKE_object_free_particlesystems(ob_to);
+ BKE_object_copy_particlesystems(ob_to, ob_from);
+
/* For remapping we need a valid DM.
* Because the modifier is appended at the end it's safe to use
* the final DM of the object without particles
*/
- if (ob_to->derivedFinal)
- final_dm = ob_to->derivedFinal;
- else
- final_dm = mesh_get_derived_final(scene, ob_to, CD_MASK_BAREMESH);
+ cdmask = 0;
+ for (psys = ob_to->particlesystem.first; psys; psys = psys->next, ++i) {
+ cdmask |= psys_emitter_customdata_mask(psys);
+ }
+ final_dm = mesh_get_derived_final(scene, ob_to, cdmask);
- BKE_object_copy_particlesystems(ob_to, ob_from);
for (psys = ob_to->particlesystem.first, psys_from = ob_from->particlesystem.first, i = 0;
psys;
psys = psys->next, psys_from = psys_from->next, ++i) {
@@ -988,14 +993,23 @@ static bool copy_particle_systems_to_object(Scene *scene, Object *ob_from, Objec
psmd->psys = psys;
psmd->dm = CDDM_copy(final_dm);
CDDM_calc_normals(psmd->dm);
+ DM_ensure_tessface(psmd->dm);
if (psys_from->edit)
copy_particle_edit(scene, ob_to, psys, psys_from);
+ }
+
+ /* note: do this after creating DM copies for all the particle system modifiers,
+ * the remapping otherwise makes final_dm invalid!
+ */
+ for (psys = ob_to->particlesystem.first, psys_from = ob_from->particlesystem.first, i = 0;
+ psys;
+ psys = psys->next, psys_from = psys_from->next, ++i) {
- remap_hair_emitter(scene, ob_from, psys_from, ob_to, psmd->dm, psys, psys->edit, false, false);
+ remap_hair_emitter(scene, ob_from, psys_from, ob_to, psys, psys->edit, false, false);
/* tag for recalc */
- psys->recalc |= PSYS_RECALC_RESET;
+// psys->recalc |= PSYS_RECALC_RESET;
}
DAG_id_tag_update(&ob_to->id, OB_RECALC_DATA);
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index a41fbb03462..9860daeda4c 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -85,37 +85,7 @@ static void copyData(ModifierData *md, ModifierData *target)
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
{
ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md;
- CustomDataMask dataMask = 0;
- MTex *mtex;
- int i;
-
- if (!psmd->psys->part)
- return 0;
-
- for (i = 0; i < MAX_MTEX; i++) {
- mtex = psmd->psys->part->mtex[i];
- if (mtex && mtex->mapto && (mtex->texco & TEXCO_UV))
- dataMask |= CD_MASK_MTFACE;
- }
-
- if (psmd->psys->part->tanfac != 0.0f)
- dataMask |= CD_MASK_MTFACE;
-
- /* ask for vertexgroups if we need them */
- for (i = 0; i < PSYS_TOT_VG; i++) {
- if (psmd->psys->vgroup[i]) {
- dataMask |= CD_MASK_MDEFORMVERT;
- break;
- }
- }
-
- /* particles only need this if they are after a non deform modifier, and
- * the modifier stack will only create them in that case. */
- dataMask |= CD_MASK_ORIGSPACE_MLOOP | CD_MASK_ORIGINDEX;
-
- dataMask |= CD_MASK_ORCO;
-
- return dataMask;
+ return psys_emitter_customdata_mask(psmd->psys);
}
/* saves the current emitter state for a particle system and calculates particles */