Commit: e395543bf7524a9344c33197dca051f6a682200f
Author: Lukas Tönne
Date:   Wed Jul 30 10:42:12 2014 +0200
Branches: hair_system
https://developer.blender.org/rBe395543bf7524a9344c33197dca051f6a682200f

Define hair root points when copying from particles, by converting
the old num/fuv data.

===================================================================

M       source/blender/blenkernel/BKE_mesh_sample.h
M       source/blender/blenkernel/BKE_particle.h
M       source/blender/blenkernel/intern/hair.c
M       source/blender/blenkernel/intern/mesh_sample.c
M       source/blender/blenkernel/intern/particle.c
M       source/blender/editors/physics/hair_ops.c
M       source/blender/editors/space_view3d/drawhair.c
M       source/blender/makesdna/DNA_hair_types.h

===================================================================

diff --git a/source/blender/blenkernel/BKE_mesh_sample.h 
b/source/blender/blenkernel/BKE_mesh_sample.h
index 6a0a892..9706bfc 100644
--- a/source/blender/blenkernel/BKE_mesh_sample.h
+++ b/source/blender/blenkernel/BKE_mesh_sample.h
@@ -76,5 +76,6 @@ void BKE_mesh_sample_info_random(struct MSurfaceSampleInfo 
*info, struct Derived
 void BKE_mesh_sample_info_release(struct MSurfaceSampleInfo *info);
 
 void BKE_mesh_sample_surface_array(const struct MSurfaceSampleInfo *info, 
struct MSurfaceSample *samples, int totsample);
+void BKE_mesh_sample_surface_array_stride(const struct MSurfaceSampleInfo 
*info, struct MSurfaceSample *first, int stride, int totsample);
 
 #endif  /* __BKE_MESH_SAMPLE_H__ */
diff --git a/source/blender/blenkernel/BKE_particle.h 
b/source/blender/blenkernel/BKE_particle.h
index f84a637..f05ccec 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -395,6 +395,7 @@ void psys_interpolate_face(struct MVert *mvert, struct 
MFace *mface, struct MTFa
                            float orco[3], float ornor[3]);
 float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, 
struct ParticleData *pa, float *values);
 void psys_get_from_key(struct ParticleKey *key, float loc[3], float vel[3], 
float rot[4], float *time);
+int psys_get_index_on_dm(struct ParticleSystem *psys, struct DerivedMesh *dm, 
ParticleData *pa, int *mapindex, float mapfw[4]);
 
 /* BLI_bvhtree_ray_cast callback */
 void BKE_psys_collision_neartest_cb(void *userdata, int index, const struct 
BVHTreeRay *ray, struct BVHTreeRayHit *hit);
diff --git a/source/blender/blenkernel/intern/hair.c 
b/source/blender/blenkernel/intern/hair.c
index ad9d9cc..e621bad 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -38,6 +38,7 @@
 #include "DNA_hair_types.h"
 
 #include "BKE_hair.h"
+#include "BKE_mesh_sample.h"
 
 HairSystem *BKE_hairsys_new(void)
 {
@@ -64,6 +65,7 @@ HairSystem *BKE_hairsys_copy(HairSystem *hsys)
 {
        int totcurves = hsys->totcurves, i;
        HairSystem *thsys = MEM_dupallocN(hsys);
+       
        thsys->curves = MEM_dupallocN(hsys->curves);
        for (i = 0; i < totcurves; ++i)
                thsys->curves[i].points = MEM_dupallocN(hsys->curves[i].points);
@@ -103,7 +105,7 @@ void BKE_hair_curve_remove(HairSystem *hsys, HairCurve 
*hair)
                memcpy(ncurves, hsys->curves, sizeof(HairCurve) * pos);
        }
        if (pos < hsys->totcurves - 1) {
-               memcpy(ncurves + pos, hsys->curves + (pos + 1), hsys->totcurves 
- (pos + 1));
+               memcpy(ncurves + pos, hsys->curves + (pos + 1), 
sizeof(HairCurve) * (hsys->totcurves - (pos + 1)));
        }
        
        MEM_freeN(hair->points);
diff --git a/source/blender/blenkernel/intern/mesh_sample.c 
b/source/blender/blenkernel/intern/mesh_sample.c
index 46e3e99..a1c3e71 100644
--- a/source/blender/blenkernel/intern/mesh_sample.c
+++ b/source/blender/blenkernel/intern/mesh_sample.c
@@ -157,13 +157,18 @@ static void mesh_sample_surface_random(const 
MSurfaceSampleInfo *info, MSurfaceS
 
 void BKE_mesh_sample_surface_array(const MSurfaceSampleInfo *info, 
MSurfaceSample *samples, int totsample)
 {
+       BKE_mesh_sample_surface_array_stride(info, samples, 
(int)sizeof(MSurfaceSample), totsample);
+}
+
+void BKE_mesh_sample_surface_array_stride(const struct MSurfaceSampleInfo 
*info, struct MSurfaceSample *first, int stride, int totsample)
+{
        MSurfaceSample *sample;
        int i;
        
        switch (info->algorithm) {
                case MSS_RANDOM: {
                        DM_ensure_tessface(info->dm);
-                       for (sample = samples, i = 0; i < totsample; ++sample, 
++i)
+                       for (sample = first, i = 0; i < totsample; sample = 
(MSurfaceSample *)((char *)sample + stride), ++i)
                                mesh_sample_surface_random(info, sample);
                        break;
                }
diff --git a/source/blender/blenkernel/intern/particle.c 
b/source/blender/blenkernel/intern/particle.c
index 27d346f..ecefec5 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1779,6 +1779,11 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int 
from, int index, int index_
        return 1;
 }
 
+int psys_get_index_on_dm(struct ParticleSystem *psys, struct DerivedMesh *dm, 
ParticleData *pa, int *mapindex, float mapfw[4])
+{
+       return psys_map_index_on_dm(dm, psys->part->from, pa->num, 
pa->num_dmcache, pa->fuv, pa->foffset, mapindex, mapfw);
+}
+
 /* interprets particle data to get a point on a mesh in object space */
 void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int 
index_dmcache,
                          const float fw[4], float foffset, float vec[3], float 
nor[3], float utan[3], float vtan[3],
diff --git a/source/blender/editors/physics/hair_ops.c 
b/source/blender/editors/physics/hair_ops.c
index ac1b4f2..19103c5 100644
--- a/source/blender/editors/physics/hair_ops.c
+++ b/source/blender/editors/physics/hair_ops.c
@@ -37,11 +37,13 @@
 #include "BLI_utildefines.h"
 
 #include "DNA_hair_types.h"
+#include "DNA_meshdata_types.h"
 #include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_particle_types.h"
 
 #include "BKE_context.h"
+#include "BKE_DerivedMesh.h"
 #include "BKE_hair.h"
 #include "BKE_modifier.h"
 #include "BKE_object.h"
@@ -122,7 +124,59 @@ void HAIR_OT_reset_to_rest_location(wmOperatorType *ot)
 
 /************************ copy hair data from old particles 
*********************/
 
-static void hair_copy_from_particles_psys(Object *ob, HairSystem *hsys, 
ParticleSystem *psys)
+static bool hair_copy_particle_emitter_location(Object *UNUSED(ob), 
ParticleSystem *psys, ParticleData *pa, struct DerivedMesh *dm, MSurfaceSample 
*result)
+{
+       float mapfw[4];
+       int mapindex;
+       MVert *mverts = dm->getVertArray(dm);
+       MFace *mface;
+       float *co1, *co2, *co3, *co4;
+       float vec[3];
+       float w[3];
+       
+       if (!psys_get_index_on_dm(psys, dm, pa, &mapindex, mapfw))
+               return false;
+       
+       mface = dm->getTessFaceData(dm, mapindex, CD_MFACE);
+       mverts = dm->getVertDataArray(dm, CD_MVERT);
+
+       co1 = mverts[mface->v1].co;
+       co2 = mverts[mface->v2].co;
+       co3 = mverts[mface->v3].co;
+
+       if (mface->v4) {
+               co4 = mverts[mface->v4].co;
+               
+               interp_v3_v3v3v3v3(vec, co1, co2, co3, co4, mapfw);
+       }
+       else {
+               interp_v3_v3v3v3(vec, co1, co2, co3, mapfw);
+       }
+       
+       /* test both triangles of the face */
+       interp_weights_face_v3(w, co1, co2, co3, NULL, vec);
+       if (w[0] <= 1.0f && w[1] <= 1.0f && w[2] <= 1.0f) {
+               result->orig_verts[0] = mface->v1;
+               result->orig_verts[1] = mface->v2;
+               result->orig_verts[2] = mface->v3;
+               
+               copy_v3_v3(result->orig_weights, w);
+               return true;
+       }
+       else if (mface->v4) {
+               interp_weights_face_v3(w, co3, co4, co1, NULL, vec);
+               result->orig_verts[0] = mface->v3;
+               result->orig_verts[1] = mface->v4;
+               result->orig_verts[2] = mface->v1;
+               
+               copy_v3_v3(result->orig_weights, w);
+               return true;
+       }
+       else
+               return false;
+}
+
+static void hair_copy_from_particles_psys(Object *ob, HairSystem *hsys, 
ParticleSystem *psys, struct DerivedMesh *dm)
 {
        HairCurve *hairs;
        int tothairs;
@@ -132,30 +186,40 @@ static void hair_copy_from_particles_psys(Object *ob, 
HairSystem *hsys, Particle
        /* matrix for bringing hairs from pob to ob space */
        invert_m4_m4(mat, ob->obmat);
        
+       /* particle emitter mesh data */
+       DM_ensure_tessface(dm);
+       
        tothairs = psys->totpart;
        hairs = BKE_hair_curve_add_multi(hsys, tothairs);
        
        for (i = 0; i < tothairs; ++i) {
                ParticleCacheKey *pa_cache = psys->pathcache[i];
+               ParticleData *root = &psys->particles[i];
                HairCurve *hair = hairs + i;
                HairPoint *points;
                int totpoints;
                
+               if (pa_cache->steps == 0)
+                       continue;
+               
                totpoints = pa_cache->steps + 1;
                points = BKE_hair_point_append_multi(hsys, hair, totpoints);
                
+               hair_copy_particle_emitter_location(ob, psys, root, dm, 
&hair->root);
+               
                for (k = 0; k < totpoints; ++k) {
                        ParticleCacheKey *pa_key = pa_cache + k;
                        HairPoint *point = points + k;
                        
                        mul_v3_m4v3(point->rest_co, mat, pa_key->co);
+                       /* apply rest position */
                        copy_v3_v3(point->co, point->rest_co);
                        zero_v3(point->vel);
                }
        }
 }
 
-static int hair_copy_from_particles_exec(bContext *C, wmOperator *UNUSED(op))
+static int hair_copy_from_particles_exec(bContext *C, wmOperator *op)
 {
        Object *ob;
        ParticleSystem *psys;
@@ -163,10 +227,20 @@ static int hair_copy_from_particles_exec(bContext *C, 
wmOperator *UNUSED(op))
        ED_hair_get(C, &ob, &hsys);
        
        for (psys = ob->particlesystem.first; psys; psys = psys->next) {
-               if (psys->part->type != PART_HAIR)
+               ParticleSystemModifierData *psmd;
+               if (psys->part->type != PART_HAIR) {
+                       BKE_reportf(op->reports, RPT_WARNING, "Skipping 
particle system %s: Not a hair particle system", psys->name);
+                       continue;
+               }
+               if (psys->part->from != PART_FROM_FACE) {
+                       BKE_reportf(op->reports, RPT_WARNING, "Skipping 
particle system %s: Must use face emitter mode", psys->name);
                        continue;
+               }
+               
+               psmd = psys_get_modifier(ob, psys);
+               BLI_assert(psmd != NULL);
                
-               hair_copy_from_particles_psys(ob, hsys, psys);
+               hair_copy_from_particles_psys(ob, hsys, psys, psmd->dm);
        }
        
        WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
diff --git a/source/blender/editors/space_view3d/drawhair.c 
b/source/blender/editors/space_view3d/drawhair.c
index a96ede3..f0e9aa8 100644
--- a/source/blender/editors/space_view3d/drawhair.c
+++ b/source/blender/editors/space_view3d/drawhair.c
@@ -41,6 +41,7 @@
 
 #include "BKE_global.h"
 #include "BKE_hair.h"
+#include "BKE_mesh_sample.h"
 #include "BKE_modifier.h"
 
 #include "view3d_intern.h"
@@ -69,6 +70,7 @@ static void draw_hair_curve(HairSystem *hsys, HairCurve *hair)
        }
        glEnd();
        
+#if 0
        /* frames */
        {
                struct HAIR_FrameIterator *iter;
@@ -121,6 +123,7 @@ static void draw_hair_curve(HairSystem *hsys, HairCurve 
*hair)
                HAIR_frame_iter_free(iter);
                glEnd();
        }
+#endif
        
 #if 0
        /* smoothed curve */
@@ -164,6 +167,7 @@ bool draw_hair_system(Scene *UNUSED(scene), View3D 
*UNUSED(v3d), ARegion *ar, Ba
 {
        RegionView3D *rv3d = ar->regiondata;
        Object *ob = base->object;
+       struct DerivedMesh *dm = ob->derivedFinal;
        HairCurve *hair;
        int i;
        bool retval = true;
@@ -171,6 +175,22 @@ bool draw_hair_system(Scene *UNUSED(scene), View3D 
*UNUSED(v3d), ARegion *ar, Ba
        glLoadMatrixf(rv3d->viewmat);
        glMultMatrixf(ob->

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to