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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2013-05-27 21:11:05 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2013-05-27 21:11:05 +0400
commitbb15701f863fbe0a40bdddc19ef949f5c59fe88b (patch)
tree04ba9b7c34a06522f54a03cc7bc2b278211aaed1 /source/blender
parent4bdb54a76e3b15f99f2efc149b9d78aeef3203a4 (diff)
Particles: patch #35205 by Jakub Zolcik
The Emission panel now has a Use Modifier Stack option to emit particles from the mesh with modifiers applied. Previously particles would only be emitted from faces that exist in the original mesh. There are some caveats however: http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.68/Tools#Particles
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/intern/particle.c2
-rw-r--r--source/blender/blenkernel/intern/particle_system.c71
-rw-r--r--source/blender/makesdna/DNA_particle_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_particle.c7
4 files changed, 67 insertions, 18 deletions
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index a95afe14a48..3ab535febb1 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -3636,6 +3636,8 @@ static void default_particle_settings(ParticleSettings *part)
if (!part->effector_weights)
part->effector_weights = BKE_add_effector_weights(NULL);
+
+ part->use_modifier_stack = false;
}
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index eb95ca16fc3..81c7fc44715 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -341,6 +341,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
* each original elements can reference its derived elements
*/
Mesh *me= (Mesh*)ob->data;
+ bool use_modifier_stack= psys->part->use_modifier_stack;
PARTICLE_P;
/* CACHE LOCATIONS */
@@ -351,17 +352,33 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
if (psys->part->from == PART_FROM_VERT) {
totdmelem= dm->getNumVerts(dm);
- totelem= me->totvert;
- origindex= dm->getVertDataArray(dm, CD_ORIGINDEX);
+
+ if (use_modifier_stack) {
+ totelem= totdmelem;
+ origindex= NULL;
+ }
+ else {
+ totelem= me->totvert;
+ origindex= dm->getVertDataArray(dm, CD_ORIGINDEX);
+ }
}
else { /* FROM_FACE/FROM_VOLUME */
totdmelem= dm->getNumTessFaces(dm);
- totelem= me->totpoly;
- origindex = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
- /* for face lookups we need the poly origindex too */
- origindex_poly = dm->getPolyDataArray(dm, CD_ORIGINDEX);
- if (origindex_poly == NULL) {
- origindex = NULL;
+
+ if (use_modifier_stack) {
+ totelem= totdmelem;
+ origindex= NULL;
+ origindex_poly= NULL;
+ }
+ else {
+ totelem= me->totpoly;
+ origindex= dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
+
+ /* for face lookups we need the poly origindex too */
+ origindex_poly= dm->getPolyDataArray(dm, CD_ORIGINDEX);
+ if (origindex_poly == NULL) {
+ origindex= NULL;
+ }
}
}
@@ -373,11 +390,16 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
node->link = SET_INT_IN_POINTER(i);
/* may be vertex or face origindex */
- origindex_final = origindex ? origindex[i] : ORIGINDEX_NONE;
+ if (use_modifier_stack) {
+ origindex_final = i;
+ }
+ else {
+ origindex_final = origindex ? origindex[i] : ORIGINDEX_NONE;
- /* if we have a poly source, do an index lookup */
- if (origindex_poly && origindex_final != ORIGINDEX_NONE) {
- origindex_final = origindex_poly[origindex_final];
+ /* if we have a poly source, do an index lookup */
+ if (origindex_poly && origindex_final != ORIGINDEX_NONE) {
+ origindex_final = origindex_poly[origindex_final];
+ }
}
if (origindex_final != ORIGINDEX_NONE) {
@@ -395,18 +417,27 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
/* cache the verts/faces! */
LOOP_PARTICLES {
if (pa->num < 0) {
- pa->num_dmcache = -1;
+ pa->num_dmcache = DMCACHE_NOTFOUND;
continue;
}
if (psys->part->from == PART_FROM_VERT) {
- if (nodearray[pa->num])
+ if (pa->num < totelem && nodearray[pa->num])
pa->num_dmcache= GET_INT_FROM_POINTER(nodearray[pa->num]->link);
+ else
+ pa->num_dmcache = DMCACHE_NOTFOUND;
}
else { /* FROM_FACE/FROM_VOLUME */
/* Note that sometimes the pa->num is over the nodearray size, this is bad, maybe there is a better place to fix this,
* but for now passing NULL is OK. every face will be searched for the particle so its slower - Campbell */
- pa->num_dmcache= psys_particle_dm_face_lookup(ob, dm, pa->num, pa->fuv, pa->num < totelem ? nodearray[pa->num] : NULL);
+ if (use_modifier_stack) {
+ if (pa->num < totelem && nodearray[pa->num])
+ pa->num_dmcache = GET_INT_FROM_POINTER(nodearray[pa->num]->link);
+ else
+ pa->num_dmcache = DMCACHE_NOTFOUND;
+ }
+ else
+ pa->num_dmcache= psys_particle_dm_face_lookup(ob, dm, pa->num, pa->fuv, pa->num < totelem ? nodearray[pa->num] : NULL);
}
}
@@ -419,7 +450,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
* an invalid value, just in case */
LOOP_PARTICLES
- pa->num_dmcache = -1;
+ pa->num_dmcache = DMCACHE_NOTFOUND;
}
}
@@ -1110,7 +1141,10 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D
distr = part->distr;
BLI_srandom(31415926 + psys->seed);
- dm= CDDM_from_mesh((Mesh*)ob->data, ob);
+ if (psys->part->use_modifier_stack)
+ dm = finaldm;
+ else
+ dm= CDDM_from_mesh((Mesh*)ob->data, ob);
/* BMESH ONLY, for verts we don't care about tessfaces */
if (from != PART_FROM_VERT) {
@@ -1118,7 +1152,8 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D
}
/* we need orco for consistent distributions */
- DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob));
+ if (!CustomData_has_layer(&dm->vertData, CD_ORCO))
+ DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, BKE_mesh_orco_verts_get(ob));
if (from == PART_FROM_VERT) {
MVert *mv= dm->getVertDataArray(dm, CD_MVERT);
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index ec2a724ac82..84442201df8 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -243,6 +243,11 @@ typedef struct ParticleSettings {
struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */
struct PartDeflect *pd;
struct PartDeflect *pd2;
+
+ /* modified dm support */
+ short use_modifier_stack;
+ short pad[3];
+
} ParticleSettings;
typedef struct ParticleSystem {
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 158377f6a8f..941437771f6 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -2916,6 +2916,13 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Loop count", "Number of times the keys are looped");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
+ /* modified dm support */
+ prop = RNA_def_property(srna, "use_modifier_stack", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "use_modifier_stack", 0);
+ RNA_def_property_ui_text(prop, "Use Modifier Stack", "Emit particles from mesh with modifiers applied"
+ "(must use same subsurf level for viewport and render for correct results)");
+ RNA_def_property_update(prop, 0, "rna_Particle_change_type");
+
/* draw objects & groups */
prop = RNA_def_property(srna, "dupli_group", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "dup_group");