Index: release/scripts/startup/bl_ui/properties_particle.py =================================================================== --- release/scripts/startup/bl_ui/properties_particle.py (revision 56488) +++ release/scripts/startup/bl_ui/properties_particle.py (working copy) @@ -249,6 +249,9 @@ elif part.distribution == 'GRID': row.prop(part, "grid_resolution") row.prop(part, "grid_random", text="Random", slider=True) + + row = layout.row() + row.prop(part, "use_modified_mesh") class PARTICLE_PT_hair_dynamics(ParticleButtonsPanel, Panel): Index: source/blender/blenkernel/intern/particle.c =================================================================== --- source/blender/blenkernel/intern/particle.c (revision 56488) +++ source/blender/blenkernel/intern/particle.c (working copy) @@ -3640,6 +3640,8 @@ if (!part->effector_weights) part->effector_weights = BKE_add_effector_weights(NULL); + + part->use_modified_mesh = 0; } Index: source/blender/blenkernel/intern/particle_system.c =================================================================== --- source/blender/blenkernel/intern/particle_system.c (revision 56488) +++ source/blender/blenkernel/intern/particle_system.c (working copy) @@ -341,6 +341,8 @@ * each original elements can reference its derived elements */ Mesh *me= (Mesh*)ob->data; + /* modified dm support */ + short use_modified_mesh = psys->part->use_modified_mesh; PARTICLE_P; /* CACHE LOCATIONS */ @@ -351,17 +353,29 @@ if (psys->part->from == PART_FROM_VERT) { totdmelem= dm->getNumVerts(dm); - totelem= me->totvert; - origindex= dm->getVertDataArray(dm, CD_ORIGINDEX); + if (use_modified_mesh) { + 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_modified_mesh) { + 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 +387,15 @@ node->link = SET_INT_IN_POINTER(i); /* may be vertex or face origindex */ - origindex_final = origindex ? origindex[i] : ORIGINDEX_NONE; + if (use_modified_mesh) + 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) { @@ -406,7 +424,10 @@ 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_modified_mesh) + pa->num_dmcache = GET_INT_FROM_POINTER(nodearray[pa->num]->link); + else + pa->num_dmcache= psys_particle_dm_face_lookup(ob, dm, pa->num, pa->fuv, pa->num < totelem ? nodearray[pa->num] : NULL); } } @@ -1110,7 +1131,10 @@ distr = part->distr; BLI_rng_srandom(ctx->sim.rng, 31415926 + psys->seed); - dm= CDDM_from_mesh((Mesh*)ob->data, ob); + if (psys->part->use_modified_mesh) + 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 +1142,8 @@ } /* 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); Index: source/blender/makesdna/DNA_particle_types.h =================================================================== --- source/blender/makesdna/DNA_particle_types.h (revision 56488) +++ source/blender/makesdna/DNA_particle_types.h (working copy) @@ -243,6 +243,11 @@ struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */ struct PartDeflect *pd; struct PartDeflect *pd2; + + /* modified dm support */ + short use_modified_mesh; + short pad[3]; + } ParticleSettings; typedef struct ParticleSystem { Index: source/blender/makesrna/intern/rna_particle.c =================================================================== --- source/blender/makesrna/intern/rna_particle.c (revision 56488) +++ source/blender/makesrna/intern/rna_particle.c (working copy) @@ -2933,6 +2933,12 @@ 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_modified_mesh", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "use_modified_mesh", 0); + RNA_def_property_ui_text(prop, "Use Modified", "Use modified mesh for emitting"); + 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");