diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_particle.py | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 71 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_particle_types.h | 5 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_particle.c | 7 |
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"); |