[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