Fix T38928 Particle add brush would generate trash on meshes with use_modifier_stack enabled

Issue here is complex (Of course, this is particles!)

First issue is that use_modifier_stack will use the num parameter of the
particles instead of num_dmcache, something the brush code did not
account for at all. Now correctly set DMCACHE_ISCHILD in that case.

Second issue is that make_derived_deform will return a mesh with less
indices than the particle system derived mesh. This would mean that
subsequent sampling of the particle derived mesh to initialize the
particles woould also produce garbage. This was being done for
optimization but in that case it broke the system.

Reviewers: lukastoenne

Differential Revision: https://developer.blender.org/D429
This commit is contained in:
Antony Riakiotakis
2014-03-26 22:24:36 +02:00
parent 859039f732
commit eca6264ab0

View File

@@ -2788,6 +2788,11 @@ static void PE_mirror_x(Scene *scene, Object *ob, int tagged)
newpa->num= mirrorfaces[pa->num*2];
newpa->num_dmcache= psys_particle_dm_face_lookup(ob, psmd->dm, newpa->num, newpa->fuv, NULL);
if ((newpa->num_dmcache != DMCACHE_NOTFOUND) && psys->part->use_modifier_stack && !psmd->dm->deformedOnly) {
newpa->num = newpa->num_dmcache;
newpa->num_dmcache = DMCACHE_ISCHILD;
}
/* update edit key pointers */
key= newpoint->keys;
for (k=0, hkey=newpa->hair; k<newpa->totkey; k++, hkey++, key++) {
@@ -3351,6 +3356,10 @@ static int brush_add(PEData *data, short number)
short size2= size*size;
DerivedMesh *dm=0;
RNG *rng;
int *index_mf_to_mpoly;
int *index_mp_to_orig;
bool release_dm = false;
invert_m4_m4(imat, ob->obmat);
if (psys->flag & PSYS_GLOBAL_HAIR)
@@ -3367,11 +3376,15 @@ static int brush_add(PEData *data, short number)
timestep= psys_get_timestep(&sim);
/* painting onto the deformed mesh, could be an option? */
if (psmd->dm->deformedOnly)
dm= psmd->dm;
else
dm= mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
if (psmd->dm->deformedOnly || psys->part->use_modifier_stack)
dm = psmd->dm;
else {
dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
release_dm = true;
}
index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
index_mp_to_orig = dm->getPolyDataArray(dm, CD_ORIGINDEX);
for (i=0; i<number; i++) {
if (number>1) {
@@ -3398,9 +3411,19 @@ static int brush_add(PEData *data, short number)
min_d=2.0;
/* warning, returns the derived mesh face */
if (particle_intersect_dm(scene, ob, dm, 0, co1, co2, &min_d, &add_pars[n].num, add_pars[n].fuv, 0, 0, 0, 0)) {
add_pars[n].num_dmcache= psys_particle_dm_face_lookup(ob, psmd->dm, add_pars[n].num, add_pars[n].fuv, NULL);
n++;
if (particle_intersect_dm(scene, ob, dm, 0, co1, co2, &min_d, &add_pars[n].num_dmcache, add_pars[n].fuv, 0, 0, 0, 0)) {
if (index_mf_to_mpoly && index_mp_to_orig)
add_pars[n].num = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, add_pars[n].num_dmcache);
else
add_pars[n].num = add_pars[n].num_dmcache;
if (psys_particle_dm_face_lookup(ob, psmd->dm, add_pars[n].num_dmcache, add_pars[n].fuv, NULL) != DMCACHE_NOTFOUND) {
if (psys->part->use_modifier_stack && !psmd->dm->deformedOnly) {
add_pars[n].num = add_pars[n].num_dmcache;
add_pars[n].num_dmcache = DMCACHE_ISCHILD;
}
n++;
}
}
}
if (n) {
@@ -3553,10 +3576,10 @@ static int brush_add(PEData *data, short number)
}
MEM_freeN(add_pars);
if (!psmd->dm->deformedOnly)
if (release_dm)
dm->release(dm);
BLI_rng_free(rng);
return n;