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:
-rw-r--r--release/scripts/startup/bl_ui/properties_particle.py6
-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
5 files changed, 73 insertions, 18 deletions
diff --git a/release/scripts/startup/bl_ui/properties_particle.py b/release/scripts/startup/bl_ui/properties_particle.py
index f949cbd9745..931b47896a6 100644
--- a/release/scripts/startup/bl_ui/properties_particle.py
+++ b/release/scripts/startup/bl_ui/properties_particle.py
@@ -213,6 +213,9 @@ class PARTICLE_PT_emission(ParticleButtonsPanel, Panel):
if part.type == 'HAIR' and not part.use_advanced_hair:
row.prop(part, "hair_length")
+
+ row = layout.row()
+ row.prop(part, "use_modifier_stack")
return
if part.type != 'HAIR':
@@ -250,6 +253,9 @@ class PARTICLE_PT_emission(ParticleButtonsPanel, Panel):
row.prop(part, "grid_resolution")
row.prop(part, "grid_random", text="Random", slider=True)
+ row = layout.row()
+ row.prop(part, "use_modifier_stack")
+
class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel):
bl_label = "Hair dynamics"
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");