"Fix" for [#23621] lattice modifier on particle hair when applied doesn't apply it...
authorJanne Karhu <jhkarh@gmail.com>
Thu, 2 Sep 2010 08:06:53 +0000 (08:06 +0000)
committerJanne Karhu <jhkarh@gmail.com>
Thu, 2 Sep 2010 08:06:53 +0000 (08:06 +0000)
* Although not strictly a bug it is the expected behavior and won't mess anything else up.
* Note: the lattice is applied to the actual hair keys instead of the calculated strands so the applied result will differ a bit from the original.

source/blender/blenkernel/BKE_particle.h
source/blender/blenkernel/intern/particle.c
source/blender/editors/object/object_modifier.c
source/blender/editors/physics/particle_edit.c

index fcef00ae9b3231b769c2f1f42b138d20f60c7342..f357e77f84ed19575dc94d832ee32ce83142e432 100644 (file)
@@ -253,6 +253,7 @@ ParticleThread *psys_threads_create(struct ParticleSimulationData *sim);
 void psys_threads_free(ParticleThread *threads);
 
 void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]);
+void psys_apply_hair_lattice(struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
 
 /* particle_system.c */
 struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt);
index 9c3a1597dd9424f7be3e434a45aaf0156872423c..45662bfbd42249cc025301413b4e558cc7785ef2 100644 (file)
@@ -4431,3 +4431,34 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3]
        VECADDFAC(center, center, yvec, bb->offset[1]);
 }
 
+
+void psys_apply_hair_lattice(Scene *scene, Object *ob, ParticleSystem *psys) {
+       ParticleSimulationData sim = {scene, ob, psys, psys_get_modifier(ob, psys)};
+
+       psys->lattice = psys_get_lattice(&sim);
+
+       if(psys->lattice) {
+               ParticleData *pa = psys->particles;
+               HairKey *hkey;
+               int p, h;
+               float hairmat[4][4], imat[4][4];
+
+               for(p=0; p<psys->totpart; p++, pa++) {
+                       psys_mat_hair_to_global(sim.ob, sim.psmd->dm, psys->part->from, pa, hairmat);
+                       invert_m4_m4(imat, hairmat);
+
+                       hkey = pa->hair;
+                       for(h=0; h<pa->totkey; h++, hkey++) {
+                               mul_m4_v3(hairmat, hkey->co);
+                               calc_latt_deform(psys->lattice, hkey->co, 1.0f);
+                               mul_m4_v3(imat, hkey->co);
+                       }
+               }
+               
+               end_latt_deform(psys->lattice);
+               psys->lattice= NULL;
+
+               /* protect the applied shape */
+               psys->flag |= PSYS_EDITED;
+       }
+}
\ No newline at end of file
index 286e953a69a9c169e772e981a68299e1a3ca0131..5cc6cb9107d30c506d94c95a37a8152144a2ef1d 100644 (file)
@@ -453,6 +453,21 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob,
                BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type");
                return 0;
        }
+
+       /* lattice modifier can be applied to particle system too */
+       if(ob->particlesystem.first) {
+
+               ParticleSystem *psys = ob->particlesystem.first;
+
+               for(; psys; psys=psys->next) {
+                       
+                       if(psys->part->type != PART_HAIR)
+                               continue;
+
+                       psys_apply_hair_lattice(scene, ob, psys);
+               }
+       }
+
        return 1;
 }
 
index d491b1a973111009d6fe3a2b4b079b9beb3cd29c..87b20ab1c4162208e1d931586d4701477426e96b 100644 (file)
@@ -4151,6 +4151,13 @@ static int clear_edited_exec(bContext *C, wmOperator *op)
                        DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
                }
        }
+       else { /* some operation might have protected hair from editing so let's clear the flag */
+               psys->recalc |= PSYS_RECALC_RESET;
+               psys->flag &= ~PSYS_GLOBAL_HAIR;
+               psys->flag &= ~PSYS_EDITED;
+               WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
+               DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+       }
 
        return OPERATOR_FINISHED;
 }