[Bf-blender-cvs] [cf11953996e] hair_guides: Fix null pointer reads when there are no hair follicles (which is allowed).

Lukas Tönne noreply at git.blender.org
Sat Nov 11 17:18:43 CET 2017


Commit: cf11953996ecda3cd3f4934007b3eeb5dfbc248d
Author: Lukas Tönne
Date:   Sat Nov 11 16:18:05 2017 +0000
Branches: hair_guides
https://developer.blender.org/rBcf11953996ecda3cd3f4934007b3eeb5dfbc248d

Fix null pointer reads when there are no hair follicles (which is allowed).

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

M	source/blender/blenkernel/intern/hair.c
M	source/blender/blenkernel/intern/hair_draw.c
M	source/blender/draw/intern/draw_cache_impl_hair.c

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

diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 3412a0fd805..01ae5b51f43 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -300,7 +300,7 @@ void BKE_hair_bind_follicles(HairSystem *hsys, struct Scene *scene)
 {
 	HairPattern *pattern = hsys->pattern;
 	const int num_strands = hsys->totcurves;
-	if (num_strands == 0)
+	if (num_strands == 0 || !pattern)
 		return;
 	
 	EvaluationContext eval_ctx = {0};
diff --git a/source/blender/blenkernel/intern/hair_draw.c b/source/blender/blenkernel/intern/hair_draw.c
index b4ba81dbf3c..135b5ec2330 100644
--- a/source/blender/blenkernel/intern/hair_draw.c
+++ b/source/blender/blenkernel/intern/hair_draw.c
@@ -116,17 +116,6 @@ typedef struct HairStrandMapTextureBuffer {
 } HairStrandMapTextureBuffer;
 BLI_STATIC_ASSERT_ALIGN(HairStrandMapTextureBuffer, 8)
 
-static void hair_get_texture_buffer_size(int numstrands, int numverts_orig, int subdiv, int numfibers,
-                                         int *r_size, int *r_strand_map_start,
-                                         int *r_strand_vertex_start, int *r_fiber_start)
-{
-	const int numverts = hair_get_strand_subdiv_numverts(numstrands, numverts_orig, subdiv);
-	*r_strand_map_start = 0;
-	*r_strand_vertex_start = *r_strand_map_start + numstrands * sizeof(HairStrandMapTextureBuffer);
-	*r_fiber_start = *r_strand_vertex_start + numverts * sizeof(HairStrandVertexTextureBuffer);
-	*r_size = *r_fiber_start + numfibers * sizeof(HairFiberTextureBuffer);
-}
-
 static void hair_strand_transport_frame(const float co1[3], const float co2[3],
                                         float prev_tang[3], float prev_nor[3],
                                         float r_tang[3], float r_nor[3])
@@ -259,17 +248,20 @@ static void hair_get_strand_buffer(
 static void hair_get_fiber_buffer(const HairSystem* hsys, DerivedMesh *scalp,
                                   HairFiberTextureBuffer *fiber_buf)
 {
-	const int totfibers = hsys->pattern->num_follicles;
-	HairFiberTextureBuffer *fb = fiber_buf;
-	
-	HairFollicle *follicle = hsys->pattern->follicles;
-	float nor[3], tang[3];
-	for (int i = 0; i < totfibers; ++i, ++fb, ++follicle) {
-		BKE_mesh_sample_eval(scalp, &follicle->mesh_sample, fb->root_position, nor, tang);
-		for (int k = 0; k < 4; ++k)
-		{
-			fb->parent_index[k] = follicle->parent_index[k];
-			fb->parent_weight[k] = follicle->parent_weight[k];
+	if (hsys->pattern)
+	{
+		const int totfibers = hsys->pattern->num_follicles;
+		HairFiberTextureBuffer *fb = fiber_buf;
+		
+		HairFollicle *follicle = hsys->pattern->follicles;
+		float nor[3], tang[3];
+		for (int i = 0; i < totfibers; ++i, ++fb, ++follicle) {
+			BKE_mesh_sample_eval(scalp, &follicle->mesh_sample, fb->root_position, nor, tang);
+			for (int k = 0; k < 4; ++k)
+			{
+				fb->parent_index[k] = follicle->parent_index[k];
+				fb->parent_weight[k] = follicle->parent_weight[k];
+			}
 		}
 	}
 }
@@ -282,8 +274,14 @@ void BKE_hair_get_texture_buffer_size(
         int *r_strand_vertex_start,
         int *r_fiber_start)
 {
-	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);
+	int numstrands = hsys->totcurves;
+	int numverts_orig = hsys->totverts;
+	int numfibers = hsys->pattern ? hsys->pattern->num_follicles : 0;
+	const int numverts = hair_get_strand_subdiv_numverts(numstrands, numverts_orig, subdiv);
+	*r_strand_map_start = 0;
+	*r_strand_vertex_start = *r_strand_map_start + numstrands * sizeof(HairStrandMapTextureBuffer);
+	*r_fiber_start = *r_strand_vertex_start + numverts * sizeof(HairStrandVertexTextureBuffer);
+	*r_size = *r_fiber_start + numfibers * sizeof(HairFiberTextureBuffer);
 }
 
 void BKE_hair_get_texture_buffer(
@@ -293,11 +291,10 @@ void BKE_hair_get_texture_buffer(
         int subdiv,
         void *buffer)
 {
-	HairPattern* pattern = hsys->pattern;
 	DerivedMesh *scalp = BKE_hair_get_scalp(hsys, scene, eval_ctx);
+	
 	int size, strand_map_start, strand_vertex_start, fiber_start;
-	hair_get_texture_buffer_size(hsys->totcurves, hsys->totverts, subdiv, pattern->num_follicles,
-	                             &size, &strand_map_start, &strand_vertex_start, &fiber_start);
+	BKE_hair_get_texture_buffer_size(hsys, subdiv, &size, &strand_map_start, &strand_vertex_start, &fiber_start);
 	
 	if (scalp)
 	{
diff --git a/source/blender/draw/intern/draw_cache_impl_hair.c b/source/blender/draw/intern/draw_cache_impl_hair.c
index c6f47951e10..913bc8ca478 100644
--- a/source/blender/draw/intern/draw_cache_impl_hair.c
+++ b/source/blender/draw/intern/draw_cache_impl_hair.c
@@ -180,7 +180,7 @@ static void hair_batch_cache_ensure_fibers(HairSystem *hsys, int subdiv, HairBat
 	GWN_VERTBUF_DISCARD_SAFE(cache->verts);
 	GWN_INDEXBUF_DISCARD_SAFE(cache->segments);
 	
-	const int totfibers = hsys->pattern->num_follicles;
+	const int totfibers = hsys->pattern ? hsys->pattern->num_follicles : 0;
 	int *fiber_lengths = BKE_hair_get_fiber_lengths(hsys, subdiv);
 	int totpoint = 0;
 	for (int i = 0; i < totfibers; ++i) {
@@ -249,7 +249,10 @@ static void hair_batch_cache_ensure_fibers(HairSystem *hsys, int subdiv, HairBat
 	fflush(stdout);
 	TIMEIT_END(data_fill);
 	
-	MEM_freeN(fiber_lengths);
+	if (fiber_lengths)
+	{
+		MEM_freeN(fiber_lengths);
+	}
 	
 	TIMEIT_BENCH(cache->segments = GWN_indexbuf_build(&elb), indexbuf_build);



More information about the Bf-blender-cvs mailing list