[Bf-blender-cvs] [1ddbde24fff] hair_guides: Add fields for curve storage in hair systems and use it in draw code.

Lukas Tönne noreply at git.blender.org
Sat Nov 11 15:14:34 CET 2017


Commit: 1ddbde24fff0e2ed2b39b135026c64238a9dda43
Author: Lukas Tönne
Date:   Sat Nov 11 14:13:47 2017 +0000
Branches: hair_guides
https://developer.blender.org/rB1ddbde24fff0e2ed2b39b135026c64238a9dda43

Add fields for curve storage in hair systems and use it in draw code.

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

M	source/blender/blenkernel/BKE_hair.h
M	source/blender/blenkernel/intern/hair.c
M	source/blender/blenkernel/intern/hair_draw.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/makesdna/DNA_hair_types.h
M	source/blender/modifiers/intern/MOD_hair.c

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

diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index 10eb7020206..986cbc3a71b 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -41,6 +41,7 @@ struct HairPattern;
 struct HairSystem;
 struct DerivedMesh;
 struct EvaluationContext;
+struct MeshSample;
 struct Scene;
 
 struct HairSystem* BKE_hair_new(void);
@@ -51,13 +52,12 @@ void BKE_hair_generate_follicles(struct HairSystem* hsys, unsigned int seed);
 
 /* === Guide Strands === */
 
+void BKE_hair_guide_curves_begin(struct HairSystem *hsys, int totcurves, int totverts);
+void BKE_hair_set_guide_curve(struct HairSystem *hsys, int index, const struct MeshSample *mesh_sample, int numverts);
+void BKE_hair_set_guide_vertex(struct HairSystem *hsys, int index, int flag, const float co[3]);
+void BKE_hair_guide_curves_end(struct HairSystem *hsys);
+
 struct DerivedMesh* BKE_hair_get_scalp(const struct HairSystem *hsys, struct Scene *scene, const struct EvaluationContext *eval_ctx);
-int BKE_hair_get_num_strands(const struct HairSystem *hsys);
-int BKE_hair_get_num_strands_verts(const struct HairSystem *hsys);
-void BKE_hair_get_strand_lengths(const struct HairSystem *hsys, int *r_lengths);
-void BKE_hair_get_strand_roots(const struct HairSystem *hsys, struct MeshSample *r_roots);
-void BKE_hair_get_strand_vertices(const struct HairSystem *hsys, float (*r_positions)[3]);
-void BKE_hair_get_follicle_weights(const struct HairSystem *hsys, unsigned int (*r_parents)[4], float (*r_weights)[4]);
 
 /* === Draw Cache === */
 
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index a268803fe25..49c72cd9f8d 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -311,6 +311,56 @@ HairFiber* BKE_hair_fibers_create(const HairDrawDataInterface *hairdata,
 
 /* ================================= */
 
+void BKE_hair_guide_curves_begin(HairSystem *hsys, int totcurves, int totverts)
+{
+	if (totcurves != hsys->totcurves)
+	{
+		hsys->curves = MEM_reallocN(hsys->curves, sizeof(HairGuideCurve) * totcurves);
+		hsys->flag |= HAIR_GUIDE_CURVES_DIRTY;
+	}
+	if (totverts != hsys->totverts)
+	{
+		hsys->verts = MEM_reallocN(hsys->curves, sizeof(HairGuideCurve) * totverts);
+		hsys->flag |= HAIR_GUIDE_VERTS_DIRTY;
+	}
+}
+
+void BKE_hair_set_guide_curve(HairSystem *hsys, int index, const MeshSample *mesh_sample, int numverts)
+{
+	BLI_assert(index <= hsys->totcurves);
+	
+	HairGuideCurve *curve = &hsys->curves[index];
+	memcpy(&curve->mesh_sample, mesh_sample, sizeof(MeshSample));
+	curve->numverts = numverts;
+	
+	hsys->flag |= HAIR_GUIDE_CURVES_DIRTY;
+}
+
+void BKE_hair_set_guide_vertex(HairSystem *hsys, int index, int flag, const float co[3])
+{
+	BLI_assert(index <= hsys->totverts);
+	
+	HairGuideVertex *vertex = &hsys->verts[index];
+	vertex->flag = flag;
+	copy_v3_v3(vertex->co, co);
+	
+	hsys->flag |= HAIR_GUIDE_VERTS_DIRTY;
+}
+
+void BKE_hair_guide_curves_end(HairSystem *hsys)
+{
+	/* Recalculate vertex offsets */
+	if (hsys->flag & HAIR_GUIDE_CURVES_DIRTY)
+	{
+		int vertstart = 0;
+		for (int i = 0; i < hsys->totcurves; ++i)
+		{
+			hsys->curves[i].vertstart = vertstart;
+			vertstart += hsys->curves[i].numverts;
+		}
+	}
+}
+
 DerivedMesh* BKE_hair_get_scalp(const HairSystem *hsys, struct Scene *scene, const struct EvaluationContext *eval_ctx)
 {
 	Object *ob = hsys->guide_object;
diff --git a/source/blender/blenkernel/intern/hair_draw.c b/source/blender/blenkernel/intern/hair_draw.c
index 0b21612d539..0da2f1b3849 100644
--- a/source/blender/blenkernel/intern/hair_draw.c
+++ b/source/blender/blenkernel/intern/hair_draw.c
@@ -53,13 +53,6 @@ BLI_INLINE int hair_get_strand_subdiv_length(int orig_length, int subdiv)
 	return ((orig_length - 1) << subdiv) + 1;
 }
 
-static void hair_get_strand_subdiv_lengths(int *lengths, const int *orig_lengths, int num_strands, int subdiv)
-{
-	for (int i = 0; i < num_strands; ++i) {
-		lengths[i] = hair_get_strand_subdiv_length(orig_lengths[i], subdiv);
-	}
-}
-
 int* BKE_hair_get_fiber_lengths(const HairSystem *hsys, int subdiv)
 {
 	if (!hsys->pattern) {
@@ -69,10 +62,12 @@ int* BKE_hair_get_fiber_lengths(const HairSystem *hsys, int subdiv)
 	const int totfibers = hsys->pattern->num_follicles;
 	int *fiber_length = MEM_mallocN(sizeof(int) * totfibers, "fiber length");
 	
-	const int num_strands = BKE_hair_get_num_strands(hsys);
+	const int num_strands = hsys->totcurves;
+	/* Cache subdivided lengths for repeated lookup */
 	int *lengths = MEM_mallocN(sizeof(int) * num_strands, "strand length");
-	BKE_hair_get_strand_lengths(hsys, lengths);
-	hair_get_strand_subdiv_lengths(lengths, lengths, num_strands, subdiv);
+	for (int i = 0; i < hsys->totcurves; ++i) {
+		lengths[i] = hair_get_strand_subdiv_length(hsys->curves[i].numverts, subdiv);
+	}
 	
 	// Calculate the length of the fiber from the weighted average of its guide strands
 	unsigned int (*parent_indices)[4] = MEM_mallocN(sizeof(unsigned int) * 4 * totfibers, "parent index");
@@ -187,24 +182,21 @@ static void hair_strand_calc_vectors(const float (*positions)[3], int num_verts,
 	}
 }
 
-static int hair_strand_subdivide(float (*verts)[3], const float (*verts_orig)[3], int numverts_orig, int subdiv)
+static int hair_strand_subdivide(const HairSystem *hsys, const HairGuideCurve* curve, int subdiv, float (*verts)[3])
 {
 	{
 		/* Move vertex positions from the dense array to their initial configuration for subdivision. */
 		const int step = (1 << subdiv);
-		const float (*src)[3] = verts_orig;
 		float (*dst)[3] = verts;
-		for (int i = 0; i < numverts_orig; ++i) {
-			copy_v3_v3(*dst, *src);
-			
-			++src;
+		for (int i = curve->vertstart; i < curve->numverts; ++i) {
+			copy_v3_v3(*dst, hsys->verts[i].co);
 			dst += step;
 		}
 	}
 	
 	/* Subdivide */
 	for (int d = 0; d < subdiv; ++d) {
-		const int num_edges = (numverts_orig - 1) << d;
+		const int num_edges = (curve->numverts - 1) << d;
 		const int hstep = 1 << (subdiv - d - 1);
 		const int step = 1 << (subdiv - d);
 		
@@ -227,64 +219,47 @@ static int hair_strand_subdivide(float (*verts)[3], const float (*verts_orig)[3]
 		}
 	}
 	
-	const int num_verts = ((numverts_orig - 1) << subdiv) + 1;
+	const int num_verts = ((curve->numverts - 1) << subdiv) + 1;
 	return num_verts;
 }
 
-static void hair_get_strand_buffer(DerivedMesh *scalp, int numstrands, int numverts_orig, int subdiv,
-                                   const int *lengths_orig, const float (*vertco_orig)[3], const MeshSample *roots,
-                                   HairStrandMapTextureBuffer *strand_map_buffer,
-                                   HairStrandVertexTextureBuffer *strand_vertex_buffer)
+static void hair_get_strand_buffer(
+        const HairSystem *hsys,
+        DerivedMesh *scalp,
+        int subdiv,
+        HairStrandMapTextureBuffer *strand_map_buffer,
+        HairStrandVertexTextureBuffer *strand_vertex_buffer)
 {
-	const int numverts = hair_get_strand_subdiv_numverts(numstrands, numverts_orig, subdiv);
+	const int numverts = hair_get_strand_subdiv_numverts(hsys->totcurves, hsys->totverts, subdiv);
 	
-	const int *lengths;
-	const float (*vertco)[3];
-	int *lengths_subdiv = NULL;
-	float (*vertco_subdiv)[3] = NULL;
-	if (subdiv > 0) {
-		lengths = lengths_subdiv = MEM_mallocN(sizeof(int) * numstrands, "strand lengths subdivided");
-		hair_get_strand_subdiv_lengths(lengths_subdiv, lengths_orig, numstrands, subdiv);
-		
-		vertco = vertco_subdiv = MEM_mallocN(sizeof(float[3]) * numverts, "strand vertex positions subdivided");
-	}
-	else {
-		lengths = lengths_orig;
-		vertco = vertco_orig;
-	}
+	float (*vertco)[3] = MEM_mallocN(sizeof(float[3]) * numverts, "strand vertex positions subdivided");
 	
 	HairStrandMapTextureBuffer *smap = strand_map_buffer;
 	HairStrandVertexTextureBuffer *svert = strand_vertex_buffer;
-	int vertex_orig_start = 0;
 	int vertex_start = 0;
-	for (int i = 0; i < numstrands; ++i) {
-		const int len_orig = lengths_orig[i];
-		const int len = lengths[i];
+	for (int i = 0; i < hsys->totcurves; ++i) {
+		const HairGuideCurve *curve = &hsys->curves[i];
+		const int len_orig = curve->numverts;
+		const int len = hair_get_strand_subdiv_length(len_orig, subdiv);
 		smap->vertex_start = vertex_start;
 		smap->vertex_count = len;
 		
 		if (subdiv > 0) {
-			hair_strand_subdivide(vertco_subdiv + vertex_start, vertco_orig + vertex_orig_start, len_orig, subdiv);
+			hair_strand_subdivide(hsys, curve, subdiv, vertco + vertex_start);
 		}
 		
 		{
 			float pos[3];
 			float matrix[3][3];
-			BKE_mesh_sample_eval(scalp, &roots[i], pos, matrix[2], matrix[0]);
+			BKE_mesh_sample_eval(scalp, &hsys->curves[i].mesh_sample, pos, matrix[2], matrix[0]);
 			cross_v3_v3v3(matrix[1], matrix[2], matrix[0]);
 			hair_strand_calc_vectors(vertco + vertex_start, len, matrix, svert);
 		}
 		
-		vertex_orig_start += len_orig;
 		vertex_start += len;
 		++smap;
 		svert += len;
 	}
-	
-	if (subdiv > 0) {
-		MEM_freeN(lengths_subdiv);
-		MEM_freeN(vertco_subdiv);
-	}
 }
 
 static void hair_get_fiber_buffer(const HairSystem* hsys, DerivedMesh *scalp,
@@ -310,9 +285,7 @@ void BKE_hair_get_texture_buffer_size(
         int *r_strand_vertex_start,
         int *r_fiber_start)
 {
-	const int totstrands = BKE_hair_get_num_strands(hsys);
-	const int totverts_orig = BKE_hair_get_num_strands_verts(hsys);
-	hair_get_texture_buffer_size(totstrands, totverts_orig, subdiv, hsys->pattern->num_follicles,
+	hair_get_texture_buffer_size(hsys->totcurves, hsys->totverts, subdiv, hsys->pattern->num_follicles,
 	                             r_size, r_strand_map_start, r_strand_vertex_start, r_fiber_start);
 }
 
@@ -325,10 +298,8 @@ void BKE_hair_get_texture_buffer(
 {
 	HairPattern* pattern = hsys->pattern;
 	DerivedMesh *scalp = BKE_hair_get_scalp(hsys, scene, eval_ctx);
-	const int totstrands = BKE_hair_get_num_strands(hsys);
-	const int totverts_orig = BKE_hair_get_num_strands_verts(hsys);
 	int size, strand_map_start, strand_vertex_start, fiber_start;
-	hair_get_texture_buffer_size(totstrands, totverts_orig, subdiv, pattern->num_follicles,
+	hair_get_texture_buffer_size(hsys->totcurves, hsys->totverts, subdiv, pattern->num_follicle

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list