[Bf-blender-cvs] [207d4424966] hair_guides: Use a secondary cache for interpolated shape loops.

Lukas Tönne noreply at git.blender.org
Sat Dec 30 16:20:44 CET 2017


Commit: 207d442496634319ac008df71f05163adee0ad7d
Author: Lukas Tönne
Date:   Sat Dec 30 15:20:17 2017 +0000
Branches: hair_guides
https://developer.blender.org/rB207d442496634319ac008df71f05163adee0ad7d

Use a secondary cache for interpolated shape loops.

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

M	source/blender/blenkernel/intern/groom.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/draw/intern/draw_cache_impl_groom.c
M	source/blender/editors/groom/editgroom.c
M	source/blender/makesdna/DNA_groom_types.h

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

diff --git a/source/blender/blenkernel/intern/groom.c b/source/blender/blenkernel/intern/groom.c
index a6e2a6ec789..2bbe3170455 100644
--- a/source/blender/blenkernel/intern/groom.c
+++ b/source/blender/blenkernel/intern/groom.c
@@ -79,9 +79,13 @@ static void groom_bundles_free(ListBase *bundles)
 {
 	for (GroomBundle *bundle = bundles->first; bundle; bundle = bundle->next)
 	{
-		if (bundle->curve_cache)
+		if (bundle->curvecache)
 		{
-			MEM_freeN(bundle->curve_cache);
+			MEM_freeN(bundle->curvecache);
+		}
+		if (bundle->shapecache)
+		{
+			MEM_freeN(bundle->shapecache);
 		}
 		if (bundle->sections)
 		{
@@ -132,9 +136,13 @@ void BKE_groom_copy_data(Main *UNUSED(bmain), Groom *groom_dst, const Groom *gro
 	BLI_duplicatelist(&groom_dst->bundles, &groom_src->bundles);
 	for (GroomBundle *bundle = groom_dst->bundles.first; bundle; bundle = bundle->next)
 	{
-		if (bundle->curve_cache)
+		if (bundle->curvecache)
+		{
+			bundle->curvecache = MEM_dupallocN(bundle->curvecache);
+		}
+		if (bundle->shapecache)
 		{
-			bundle->curve_cache = MEM_dupallocN(bundle->curve_cache);
+			bundle->shapecache = MEM_dupallocN(bundle->shapecache);
 		}
 		if (bundle->sections)
 		{
@@ -206,34 +214,6 @@ void BKE_groom_boundbox_calc(Groom *groom, float r_loc[3], float r_size[3])
 
 /* === Depsgraph evaluation === */
 
-/* linear bspline section eval */
-static void groom_eval_curve_cache_section_linear(
-        GroomBundle *bundle,
-        int isection,
-        int curve_res)
-{
-	BLI_assert(bundle->totsections > 1);
-	BLI_assert(isection < bundle->totsections - 1);
-	BLI_assert(curve_res >= 1);
-	
-	GroomSection *section = &bundle->sections[isection];
-	const float *co0 = section->center;
-	const float *co1 = (section+1)->center;
-	
-	float dx[3];
-	sub_v3_v3v3(dx, co1, co0);
-	mul_v3_fl(dx, 1.0f / curve_res);
-	
-	GroomCurveCache *cache = bundle->curve_cache + curve_res * isection;
-	float x[3];
-	copy_v3_v3(x, co0);
-	for (int i = 0; i <= curve_res; ++i, ++cache)
-	{
-		copy_v3_v3(cache->co, x);
-		add_v3_v3(x, dx);
-	}
-}
-
 /* forward differencing method for cubic polynomial eval */
 static void groom_forward_diff_cubic(float a, float b, float c, float d, float *p, int it, int stride)
 {
@@ -257,17 +237,17 @@ static void groom_forward_diff_cubic(float a, float b, float c, float d, float *
 }
 
 /* cubic bspline section eval */
-static void groom_eval_curve_cache_section_cubic(
+static void groom_eval_curve_cache_section(
         GroomBundle *bundle,
         int isection,
         int curve_res)
 {
-	BLI_assert(bundle->totsections > 2);
+	BLI_assert(bundle->totsections >= 2);
 	BLI_assert(isection < bundle->totsections - 1);
 	BLI_assert(curve_res >= 1);
 	
 	GroomSection *section = &bundle->sections[isection];
-	GroomCurveCache *cache = bundle->curve_cache + curve_res * isection;
+	GroomCurveCache *cache = bundle->curvecache + curve_res * isection;
 	
 	const float *co0 = (section-1)->center;
 	const float *co1 = section->center;
@@ -279,19 +259,22 @@ static void groom_eval_curve_cache_section_cubic(
 	{
 		/* define tangents from segment direction */
 		float n1, n2;
+		
 		if (isection == 0)
 		{
 			n1 = co2[k] - co1[k];
-			n2 = 0.5f * (co3[k] - co1[k]);
 		}
-		else if (isection == bundle->totsections - 2)
+		else
 		{
 			n1 = 0.5f * (co2[k] - co0[k]);
+		}
+		
+		if (isection == bundle->totsections - 2)
+		{
 			n2 = co2[k] - co1[k];
 		}
 		else
 		{
-			n1 = 0.5f * (co2[k] - co0[k]);
 			n2 = 0.5f * (co3[k] - co1[k]);
 		}
 		
@@ -305,6 +288,64 @@ static void groom_eval_curve_cache_section_cubic(
 	}
 }
 
+/* cubic bspline section eval */
+static void groom_eval_shape_cache_section(
+        GroomBundle *bundle,
+        int isection,
+        int curve_res)
+{
+	BLI_assert(bundle->totsections > 1);
+	BLI_assert(isection < bundle->totsections - 1);
+	BLI_assert(curve_res >= 1);
+	
+	const int numloopverts = bundle->numloopverts;
+	GroomSectionVertex *loop0 = &bundle->verts[numloopverts * (isection-1)];
+	GroomSectionVertex *loop1 = &bundle->verts[numloopverts * isection];
+	GroomSectionVertex *loop2 = &bundle->verts[numloopverts * (isection+1)];
+	GroomSectionVertex *loop3 = &bundle->verts[numloopverts * (isection+2)];
+	GroomShapeCache *cache = bundle->shapecache + curve_res * numloopverts * isection;
+	for (int v = 0; v < numloopverts; ++v, ++loop0, ++loop1, ++loop2, ++loop3, ++cache)
+	{
+		const float *co0 = loop0->co;
+		const float *co1 = loop1->co;
+		const float *co2 = loop2->co;
+		const float *co3 = loop3->co;
+		
+		float a, b, c, d;
+		for (int k = 0; k < 2; ++k)
+		{
+			/* define tangents from segment direction */
+			float n1, n2;
+			
+			if (isection == 0)
+			{
+				n1 = co2[k] - co1[k];
+			}
+			else
+			{
+				n1 = 0.5f * (co2[k] - co0[k]);
+			}
+			
+			if (isection == bundle->totsections - 2)
+			{
+				n2 = co2[k] - co1[k];
+			}
+			else
+			{
+				n2 = 0.5f * (co3[k] - co1[k]);
+			}
+			
+			/* Hermite spline interpolation */
+			a = 2.0f * (co1[k] - co2[k]) + n1 + n2;
+			b = 3.0f * (co2[k] - co1[k]) - 2.0f * n1 - n2;
+			c = n1;
+			d = co1[k];
+			
+			groom_forward_diff_cubic(a, b, c, d, cache->co + k, curve_res, sizeof(GroomShapeCache) * numloopverts);
+		}
+	}
+}
+
 static void groom_eval_curve_step(float mat[3][3], const float mat_prev[3][3], const float co0[3], const float co1[3])
 {
 	float dir[3];
@@ -357,29 +398,36 @@ void BKE_groom_eval_curve_cache(const EvaluationContext *UNUSED(eval_ctx), Scene
 		if (totsections == 0)
 		{
 			/* clear cache */
-			if (bundle->curve_cache)
+			if (bundle->curvecache)
 			{
-				MEM_freeN(bundle->curve_cache);
-				bundle->curve_cache = NULL;
-				bundle->totcache = 0;
+				MEM_freeN(bundle->curvecache);
+				bundle->curvecache = NULL;
+				bundle->totcurvecache = 0;
+			}
+			if (bundle->shapecache)
+			{
+				MEM_freeN(bundle->shapecache);
+				bundle->shapecache = NULL;
+				bundle->totshapecache = 0;
 			}
 			
 			/* nothing to do */
 			continue;
 		}
 		
-		bundle->totcache = (totsections-1) * groom->curve_res + 1;
-		bundle->curve_cache = MEM_reallocN_id(bundle->curve_cache, sizeof(GroomCurveCache) * bundle->totcache, "groom bundle curve cache");
+		bundle->totcurvecache = (totsections-1) * groom->curve_res + 1;
+		bundle->totshapecache = bundle->totcurvecache * bundle->numloopverts;
+		bundle->curvecache = MEM_reallocN_id(bundle->curvecache, sizeof(GroomCurveCache) * bundle->totcurvecache, "groom bundle curve cache");
+		bundle->shapecache = MEM_reallocN_id(bundle->shapecache, sizeof(GroomShapeCache) * bundle->totshapecache, "groom bundle shape cache");
 		
 		if (totsections == 1)
 		{
 			/* degenerate case */
-			copy_v3_v3(bundle->curve_cache[0].co, bundle->sections[0].center);
-		}
-		else if (totsections == 2)
-		{
-			/* single section, linear */
-			groom_eval_curve_cache_section_linear(bundle, 0, groom->curve_res);
+			copy_v3_v3(bundle->curvecache[0].co, bundle->sections[0].center);
+			for (int i = 0; i < bundle->numloopverts; ++i)
+			{
+				copy_v2_v2(bundle->shapecache[i].co, bundle->verts[i].co);
+			}
 		}
 		else
 		{
@@ -387,18 +435,19 @@ void BKE_groom_eval_curve_cache(const EvaluationContext *UNUSED(eval_ctx), Scene
 			GroomSection *section = bundle->sections;
 			for (int i = 0; i < totsections-1; ++i, ++section)
 			{
-				groom_eval_curve_cache_section_cubic(bundle, i, groom->curve_res);
+				groom_eval_curve_cache_section(bundle, i, groom->curve_res);
+				groom_eval_shape_cache_section(bundle, i, groom->curve_res);
 			}
 		}
 		
 		float basemat[3][3];
 		unit_m3(basemat); // TODO
-		groom_eval_curve_cache_mats(bundle->curve_cache, bundle->totcache, basemat);
+		groom_eval_curve_cache_mats(bundle->curvecache, bundle->totcurvecache, basemat);
 		
 		/* Copy coordinate frame to sections */
 		{
 			GroomSection *section = bundle->sections;
-			GroomCurveCache *cache = bundle->curve_cache;
+			GroomCurveCache *cache = bundle->curvecache;
 			for (int i = 0; i < totsections; ++i, ++section, cache += groom->curve_res)
 			{
 				copy_m3_m3(section->mat, cache->mat);
@@ -411,11 +460,17 @@ static void groom_bundles_curve_cache_clear(ListBase *bundles)
 {
 	for (GroomBundle *bundle = bundles->first; bundle; bundle = bundle->next)
 	{
-		if (bundle->curve_cache)
+		if (bundle->curvecache)
+		{
+			MEM_freeN(bundle->curvecache);
+			bundle->curvecache = NULL;
+			bundle->totcurvecache = 0;
+		}
+		if (bundle->shapecache)
 		{
-			MEM_freeN(bundle->curve_cache);
-			bundle->curve_cache = NULL;
-			bundle->totcache = 0;
+			MEM_freeN(bundle->shapecache);
+			bundle->shapecache = NULL;
+			bundle->totshapecache = 0;
 		}
 	}
 }
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 8bec2f47d12..acd2468a22e 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -8400,8 +8400,10 @@ static void direct_link_groom(FileData *fd, Groom *groom)
 	{
 		bundle->sections = newdataadr(fd, bundle->sections);
 		bundle->verts = newdataadr(fd, bundle->verts);
-		bundle->curve_cache = NULL;
-		bundle->totcache = 0;
+		bundle->curvecache = NULL;
+		bundle->shapecache = NULL;
+		bundle->totcurvecache = 0;
+		bundle->totshapecache = 0;
 	}
 	
 	groom->bb = NULL;
diff --git a/source/blender/draw/intern/draw_cache_impl_groom.c b/source/blender/draw/intern/draw_cache_impl_groom.c
index 16f8886e010..25a02af6384 100644
--- a/source/blender/draw/intern/draw_cache_impl_groom.c
+++ b/source/blender/draw/intern/draw_cache_impl_groom.c
@@ -206,7 +206,7 @@ static int groom_count_verts(Groom *groom, int parts, bool use_curve_cache)
 		{
 			if (use_curve_cache)
 			{
-				vert_len += bundle->totcache;
+				vert_len += bundle->totcurvecache;
 			}
 			else
 			{
@@ -218,7 +218,14 @@ static int groom_count_verts(Groom *groom, int parts, bool use_curve_cache)
 	{
 		for (GroomBundle *bundle = bundles->first; bundle; bundle = bundle->next)
 		{
-			vert_len += bundle->totverts;
+			if (use_curve_cache)
+			{
+				vert_len += bundle->totshapecache;
+			}
+			else
+			{
+				vert_len += bundle->totverts;
+			}
 		}
 	}
 	
@@ -240,9 +247,9 @@ static int groom_count_edges(Groom *groom, int parts, bool use_curve_cache)
 		{
 			if (use_curve_cache)
 			{
-				if (bundle->totc

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list