[Bf-blender-cvs] [9e62c2f] temp_merge_gooseberry_hair: Fix for particle system copy: This has to make sure the ORIGSPACE data layer is available.

Lukas Tönne noreply at git.blender.org
Mon Jan 19 20:52:10 CET 2015


Commit: 9e62c2fb76e570d4012d7afeda1c1e55aea7625e
Author: Lukas Tönne
Date:   Thu Jan 15 18:15:52 2015 +0100
Branches: temp_merge_gooseberry_hair
https://developer.blender.org/rB9e62c2fb76e570d4012d7afeda1c1e55aea7625e

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.

===================================================================

M	source/blender/blenkernel/BKE_particle.h
M	source/blender/blenkernel/intern/particle.c
M	source/blender/editors/physics/particle_object.c
M	source/blender/modifiers/intern/MOD_particlesystem.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 24e7581..d745fa2 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 927d7b7..5bee342 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1645,6 +1645,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 33bf2b8..c7794d3 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 a41fbb0..9860dae 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 */




More information about the Bf-blender-cvs mailing list