[Bf-blender-cvs] [e395543] hair_system: Define hair root points when copying from particles, by converting the old num/fuv data.

Lukas Tönne noreply at git.blender.org
Wed Jul 30 10:43:32 CEST 2014


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. @@




More information about the Bf-blender-cvs mailing list