[Bf-blender-cvs] [64e3744e8b5] hair_guides: Make Mesh based eval the default for mesh sampling (generators unchanged).

Lukas Tönne noreply at git.blender.org
Wed May 23 10:04:33 CEST 2018


Commit: 64e3744e8b5b2b800c5379a1826350fff7650413
Author: Lukas Tönne
Date:   Tue May 22 10:39:11 2018 +0100
Branches: hair_guides
https://developer.blender.org/rB64e3744e8b5b2b800c5379a1826350fff7650413

Make Mesh based eval the default for mesh sampling (generators unchanged).

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

M	source/blender/blenkernel/BKE_mesh_sample.h
M	source/blender/blenkernel/intern/hair.c
M	source/blender/blenkernel/intern/mesh_sample.c
M	source/blender/draw/intern/draw_cache_impl_hair.c
M	tests/gtests/blenkernel/BKE_mesh_sample_test.cc

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

diff --git a/source/blender/blenkernel/BKE_mesh_sample.h b/source/blender/blenkernel/BKE_mesh_sample.h
index 03c30170d72..8b461ceb8b1 100644
--- a/source/blender/blenkernel/BKE_mesh_sample.h
+++ b/source/blender/blenkernel/BKE_mesh_sample.h
@@ -52,7 +52,13 @@ void BKE_mesh_sample_weights_from_loc(struct MeshSample *sample, struct DerivedM
 bool BKE_mesh_sample_is_valid(const struct MeshSample *sample);
 bool BKE_mesh_sample_is_volume_sample(const struct MeshSample *sample);
 
-bool BKE_mesh_sample_eval(struct DerivedMesh *dm, const struct MeshSample *sample, float loc[3], float nor[3], float tang[3]);
+/* Evaluate position and normal on the given mesh */
+bool BKE_mesh_sample_eval(struct Mesh *mesh, const struct MeshSample *sample, float loc[3], float nor[3], float tang[3]);
+
+/* Evaluate position and normal on the given mesh */
+bool BKE_mesh_sample_eval_DM(struct DerivedMesh *dm, const struct MeshSample *sample, float loc[3], float nor[3], float tang[3]);
+
+/* Evaluate position for the given shapekey */
 bool BKE_mesh_sample_shapekey(struct Key *key, struct KeyBlock *kb, const struct MeshSample *sample, float loc[3]);
 
 void BKE_mesh_sample_clear(struct MeshSample *sample);
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index f090ecfd5aa..40f2cbb0de9 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -417,7 +417,7 @@ void BKE_hair_bind_follicles(HairSystem *hsys, DerivedMesh *scalp)
 	{
 		for (int i = 0; i < num_strands; ++i) {
 			float nor[3], tang[3];
-			if (!BKE_mesh_sample_eval(scalp, &hsys->guides.curves[i].mesh_sample, strandloc[i], nor, tang)) {
+			if (!BKE_mesh_sample_eval_DM(scalp, &hsys->guides.curves[i].mesh_sample, strandloc[i], nor, tang)) {
 				zero_v3(strandloc[i]);
 			}
 		}
@@ -432,7 +432,7 @@ void BKE_hair_bind_follicles(HairSystem *hsys, DerivedMesh *scalp)
 	HairFollicle *follicle = pattern->follicles;
 	for (int i = 0; i < pattern->num_follicles; ++i, ++follicle) {
 		float loc[3], nor[3], tang[3];
-		if (BKE_mesh_sample_eval(scalp, &follicle->mesh_sample, loc, nor, tang)) {
+		if (BKE_mesh_sample_eval_DM(scalp, &follicle->mesh_sample, loc, nor, tang)) {
 			hair_fiber_find_closest_strand(follicle, loc, tree, strandloc);
 			hair_fiber_verify_weights(follicle);
 		}
@@ -608,7 +608,7 @@ int BKE_hair_export_cache_update(HairExportCache *cache, const HairSystem *hsys,
 				/* Root matrix for defining the initial normal direction */
 				float rootpos[3];
 				float rootmat[3][3];
-				BKE_mesh_sample_eval(scalp, &curve->mesh_sample, rootpos, rootmat[2], rootmat[0]);
+				BKE_mesh_sample_eval_DM(scalp, &curve->mesh_sample, rootpos, rootmat[2], rootmat[0]);
 				cross_v3_v3v3(rootmat[1], rootmat[2], rootmat[0]);
 				
 				hair_guide_calc_vectors(verts, curve->numverts, rootmat, tangents, normals);
@@ -664,7 +664,7 @@ int BKE_hair_export_cache_update(HairExportCache *cache, const HairSystem *hsys,
 			for (int i = 0; i < totfibercurves; ++i, ++follicle) {
 				/* Cache fiber root position */
 				float nor[3], tang[3];
-				BKE_mesh_sample_eval(scalp, &follicle->mesh_sample, cache->fiber_root_position[i], nor, tang);
+				BKE_mesh_sample_eval_DM(scalp, &follicle->mesh_sample, cache->fiber_root_position[i], nor, tang);
 			}
 		}
 	}
diff --git a/source/blender/blenkernel/intern/mesh_sample.c b/source/blender/blenkernel/intern/mesh_sample.c
index 68b07143574..a09ef3e3fd9 100644
--- a/source/blender/blenkernel/intern/mesh_sample.c
+++ b/source/blender/blenkernel/intern/mesh_sample.c
@@ -207,7 +207,79 @@ bool BKE_mesh_sample_is_volume_sample(const MeshSample *sample)
 	return v[0] == SAMPLE_INDEX_INVALID && v[1] == SAMPLE_INDEX_INVALID && v[2] == SAMPLE_INDEX_INVALID;
 }
 
-bool BKE_mesh_sample_eval(DerivedMesh *dm, const MeshSample *sample, float loc[3], float nor[3], float tang[3])
+/* Evaluate position and normal on the given mesh */
+
+bool BKE_mesh_sample_eval(Mesh *mesh, const MeshSample *sample, float loc[3], float nor[3], float tang[3])
+{
+	const MVert *mverts = mesh->mvert;
+	const unsigned int totverts = (unsigned int)mesh->totvert;
+	const MVert *v1, *v2, *v3;
+	
+	zero_v3(loc);
+	zero_v3(nor);
+	zero_v3(tang);
+	
+	if (BKE_mesh_sample_is_volume_sample(sample)) {
+		/* VOLUME SAMPLE */
+		
+		if (is_zero_v3(sample->orig_weights))
+			return false;
+		
+		copy_v3_v3(loc, sample->orig_weights);
+		return true;
+	}
+	else {
+		/* SURFACE SAMPLE */
+		if (sample->orig_verts[0] >= totverts ||
+		    sample->orig_verts[1] >= totverts ||
+		    sample->orig_verts[2] >= totverts)
+			return false;
+		
+		v1 = &mverts[sample->orig_verts[0]];
+		v2 = &mverts[sample->orig_verts[1]];
+		v3 = &mverts[sample->orig_verts[2]];
+		
+		{ /* location */
+			madd_v3_v3fl(loc, v1->co, sample->orig_weights[0]);
+			madd_v3_v3fl(loc, v2->co, sample->orig_weights[1]);
+			madd_v3_v3fl(loc, v3->co, sample->orig_weights[2]);
+		}
+		
+		{ /* normal */
+			float vnor[3];
+			
+			normal_short_to_float_v3(vnor, v1->no);
+			madd_v3_v3fl(nor, vnor, sample->orig_weights[0]);
+			normal_short_to_float_v3(vnor, v2->no);
+			madd_v3_v3fl(nor, vnor, sample->orig_weights[1]);
+			normal_short_to_float_v3(vnor, v3->no);
+			madd_v3_v3fl(nor, vnor, sample->orig_weights[2]);
+			
+			normalize_v3(nor);
+		}
+		
+		{ /* tangent */
+			float edge[3];
+			
+			/* XXX simply using the v1-v2 edge as a tangent vector for now ...
+			 * Eventually mikktspace generated tangents (CD_TANGENT tessface layer)
+			 * should be used for consistency, but requires well-defined tessface
+			 * indices for the mesh surface samples.
+			 */
+			
+			sub_v3_v3v3(edge, v2->co, v1->co);
+			/* make edge orthogonal to nor */
+			madd_v3_v3fl(edge, nor, -dot_v3v3(edge, nor));
+			normalize_v3_v3(tang, edge);
+		}
+		
+		return true;
+	}
+}
+
+/* Evaluate position and normal on the given mesh */
+
+bool BKE_mesh_sample_eval_DM(DerivedMesh *dm, const MeshSample *sample, float loc[3], float nor[3], float tang[3])
 {
 	MVert *mverts = dm->getVertArray(dm);
 	unsigned int totverts = (unsigned int)dm->getNumVerts(dm);
@@ -275,6 +347,8 @@ bool BKE_mesh_sample_eval(DerivedMesh *dm, const MeshSample *sample, float loc[3
 	}
 }
 
+/* Evaluate position for the given shapekey */
+
 bool BKE_mesh_sample_shapekey(Key *key, KeyBlock *kb, const MeshSample *sample, float loc[3])
 {
 	float *v1, *v2, *v3;
@@ -852,7 +926,7 @@ static void generator_poissondisk_uniform_sample_eval(
 	memcpy(isample->orig_verts, sample->orig_verts, sizeof(isample->orig_verts));
 	memcpy(isample->orig_weights, sample->orig_weights, sizeof(isample->orig_weights));
 	float nor[3], tang[3];
-	BKE_mesh_sample_eval(dm, sample, isample->co, nor, tang);
+	BKE_mesh_sample_eval_DM(dm, sample, isample->co, nor, tang);
 	
 	poissondisk_grid_from_loc(gen, isample->cell_index, isample->co);
 }
diff --git a/source/blender/draw/intern/draw_cache_impl_hair.c b/source/blender/draw/intern/draw_cache_impl_hair.c
index cc8e9ba0877..9eeb473e17e 100644
--- a/source/blender/draw/intern/draw_cache_impl_hair.c
+++ b/source/blender/draw/intern/draw_cache_impl_hair.c
@@ -357,7 +357,7 @@ static void hair_batch_cache_ensure_follicles(
 	HairFollicle *follicle = pattern->follicles;
 	for (int i = 0; i < pattern->num_follicles; ++i, ++follicle) {
 		float co[3], nor[3], tang[3];
-		BKE_mesh_sample_eval(scalp, &follicle->mesh_sample, co, nor, tang);
+		BKE_mesh_sample_eval_DM(scalp, &follicle->mesh_sample, co, nor, tang);
 		
 		GWN_vertbuf_attr_set(cache->follicle_verts, pos_id, (unsigned int)i, co);
 	}
diff --git a/tests/gtests/blenkernel/BKE_mesh_sample_test.cc b/tests/gtests/blenkernel/BKE_mesh_sample_test.cc
index 34c0b82342f..27fd81e49de 100644
--- a/tests/gtests/blenkernel/BKE_mesh_sample_test.cc
+++ b/tests/gtests/blenkernel/BKE_mesh_sample_test.cc
@@ -152,7 +152,7 @@ void MeshSampleTest::dump_samples()
 	}
 	for (int i = 0; i < m_numsamples; ++i) {
 		float nor[3], tang[3];
-		BKE_mesh_sample_eval(m_dm, &m_samples[i], dbg_verts[numverts + i], nor, tang);
+		BKE_mesh_sample_eval_DM(m_dm, &m_samples[i], dbg_verts[numverts + i], nor, tang);
 	}
 	int *dbg_faces = (int *)MEM_mallocN(sizeof(int) * m_mesh->totloop, "faces");
 	int *dbg_face_lengths = (int *)MEM_mallocN(sizeof(int) * m_mesh->totpoly, "face_lengths");



More information about the Bf-blender-cvs mailing list