[Bf-blender-cvs] [e421ba71442] hair_guides: Parent indices and weights for hair follicles and a binding function.
Lukas Tönne
noreply at git.blender.org
Sat Nov 11 16:57:55 CET 2017
Commit: e421ba714424347aafce96b37bce4caffc9a03bf
Author: Lukas Tönne
Date: Sat Nov 11 15:57:31 2017 +0000
Branches: hair_guides
https://developer.blender.org/rBe421ba714424347aafce96b37bce4caffc9a03bf
Parent indices and weights for hair follicles and a binding function.
===================================================================
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/makesdna/DNA_hair_types.h
===================================================================
diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index 986cbc3a71b..dc3cc5a1651 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -48,8 +48,6 @@ struct HairSystem* BKE_hair_new(void);
struct HairSystem* BKE_hair_copy(struct HairSystem *hsys);
void BKE_hair_free(struct HairSystem *hsys);
-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);
@@ -59,6 +57,12 @@ 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);
+/* === Follicles === */
+
+void BKE_hair_generate_follicles(struct HairSystem* hsys, unsigned int seed);
+
+void BKE_hair_bind_follicles(struct HairSystem *hsys, struct Scene *scene);
+
/* === Draw Cache === */
enum {
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 49c72cd9f8d..3412a0fd805 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -49,6 +49,8 @@
#include "BKE_mesh_sample.h"
#include "BKE_hair.h"
+#include "DEG_depsgraph.h"
+
#include "BLT_translation.h"
HairSystem* BKE_hair_new(void)
@@ -136,10 +138,83 @@ void BKE_hair_follicles_generate(HairPattern *hair, DerivedMesh *scalp, int coun
}
#endif
-#if 0
-BLI_INLINE void verify_fiber_weights(HairFiber *fiber)
+/* ================================= */
+
+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)
{
- const float *w = fiber->parent_weight;
+ Object *ob = hsys->guide_object;
+
+ if (ob)
+ {
+ if (eval_ctx)
+ {
+ CustomDataMask datamask = CD_MASK_BAREMESH;
+ return mesh_get_derived_final(eval_ctx, scene, ob, datamask);
+ }
+ else
+ {
+ return ob->derivedFinal;
+ }
+ }
+
+ return NULL;
+}
+
+/* ================================= */
+
+BLI_INLINE void hair_fiber_verify_weights(HairFollicle *follicle)
+{
+ const float *w = follicle->parent_weight;
BLI_assert(w[0] >= 0.0f && w[1] >= 0.0f && w[2] >= 0.0f && w[3] >= 0.0f);
float sum = w[0] + w[1] + w[2] + w[3];
@@ -150,10 +225,10 @@ BLI_INLINE void verify_fiber_weights(HairFiber *fiber)
BLI_assert(w[0] >= w[1] && w[1] >= w[2] && w[2] >= w[3]);
}
-static void sort_fiber_weights(HairFiber *fiber)
+static void hair_fiber_sort_weights(HairFollicle *follicle)
{
- unsigned int *idx = fiber->parent_index;
- float *w = fiber->parent_weight;
+ unsigned int *idx = follicle->parent_index;
+ float *w = follicle->parent_weight;
#define FIBERSWAP(a, b) \
SWAP(unsigned int, idx[a], idx[b]); \
@@ -175,8 +250,11 @@ static void sort_fiber_weights(HairFiber *fiber)
#undef FIBERSWAP
}
-static void strand_find_closest(HairFiber *fiber, const float loc[3],
- const KDTree *tree, const float (*strandloc)[3])
+static void hair_fiber_find_closest_strand(
+ HairFollicle *follicle,
+ const float loc[3],
+ const KDTree *tree,
+ const float (*strandloc)[3])
{
/* Use the 3 closest strands for interpolation.
* Note that we have up to 4 possible weights, but we
@@ -186,12 +264,12 @@ static void strand_find_closest(HairFiber *fiber, const float loc[3],
const float *sloc[3] = {NULL};
int k, found = BLI_kdtree_find_nearest_n(tree, loc, nearest, 3);
for (k = 0; k < found; ++k) {
- fiber->parent_index[k] = nearest[k].index;
+ follicle->parent_index[k] = (unsigned int)nearest[k].index;
sloc[k] = strandloc[nearest[k].index];
}
for (; k < 4; ++k) {
- fiber->parent_index[k] = STRAND_INDEX_NONE;
- fiber->parent_weight[k] = 0.0f;
+ follicle->parent_index[k] = HAIR_STRAND_INDEX_NONE;
+ follicle->parent_weight[k] = 0.0f;
}
/* calculate barycentric interpolation weights */
@@ -201,56 +279,42 @@ static void strand_find_closest(HairFiber *fiber, const float loc[3],
float w[3];
interp_weights_tri_v3(w, sloc[0], sloc[1], sloc[2], closest);
- copy_v3_v3(fiber->parent_weight, w);
+ copy_v3_v3(follicle->parent_weight, w);
/* float precisions issues can cause slightly negative weights */
- CLAMP3(fiber->parent_weight, 0.0f, 1.0f);
+ CLAMP3(follicle->parent_weight, 0.0f, 1.0f);
}
else if (found == 2) {
- fiber->parent_weight[1] = line_point_factor_v3(loc, sloc[0], sloc[1]);
- fiber->parent_weight[0] = 1.0f - fiber->parent_weight[1];
+ follicle->parent_weight[1] = line_point_factor_v3(loc, sloc[0], sloc[1]);
+ follicle->parent_weight[0] = 1.0f - follicle->parent_weight[1];
/* float precisions issues can cause slightly negative weights */
- CLAMP2(fiber->parent_weight, 0.0f, 1.0f);
+ CLAMP2(follicle->parent_weight, 0.0f, 1.0f);
}
else if (found == 1) {
- fiber->parent_weight[0] = 1.0f;
+ follicle->parent_weight[0] = 1.0f;
}
- sort_fiber_weights(fiber);
+ hair_fiber_sort_weights(follicle);
}
-static void strand_calc_root_distance(HairFiber *fiber, const float loc[3], const float nor[3], const float tang[3],
- const float (*strandloc)[3])
+void BKE_hair_bind_follicles(HairSystem *hsys, struct Scene *scene)
{
- if (fiber->parent_index[0] == STRAND_INDEX_NONE)
- return;
-
- float cotang[3];
- cross_v3_v3v3(cotang, nor, tang);
-
- const float *sloc0 = strandloc[fiber->parent_index[0]];
- float dist[3];
- sub_v3_v3v3(dist, loc, sloc0);
- fiber->root_distance[0] = dot_v3v3(dist, tang);
- fiber->root_distance[1] = dot_v3v3(dist, cotang);
-}
-
-static void strands_calc_weights(const HairDrawDataInterface *hairdata, struct DerivedMesh *scalp, HairFiber *fibers, int num_fibers)
-{
- const int num_strands = hairdata->get_num_strands(hairdata);
+ HairPattern *pattern = hsys->pattern;
+ const int num_strands = hsys->totcurves;
if (num_strands == 0)
return;
+ EvaluationContext eval_ctx = {0};
+ DEG_evaluation_context_init(&eval_ctx, DAG_EVAL_VIEWPORT);
+ DerivedMesh *scalp = BKE_hair_get_scalp(hsys, scene, &eval_ctx);
+
float (*strandloc)[3] = MEM_mallocN(sizeof(float) * 3 * num_strands, "strand locations");
{
- MeshSample *roots = MEM_mallocN(sizeof(MeshSample) * num_strands, "strand roots");
- hairdata->get_strand_roots(hairdata, roots);
for (int i = 0; i < num_strands; ++i) {
float nor[3], tang[3];
- if (!BKE_mesh_sample_eval(scalp, &roots[i], strandloc[i], nor, tang)) {
+ if (!BKE_mesh_sample_eval(scalp, &hsys->curves[i].mesh_sample, strandloc[i], nor, tang)) {
zero_v3(strandloc[i]);
}
}
- MEM_freeN(roots);
}
KDTree *tree = BLI_kdtree_new(num_strands);
@@ -259,15 +323,12 @@ static void strands_calc_weights(const HairDrawDataInterface *hairdata, struct D
}
BLI_kdtree_balance(tree);
- HairFiber *fiber = fibers;
- for (int i = 0; i < num_fibers; ++i, ++fiber) {
+ 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, &fiber->root, loc, nor, tang)) {
-
- strand_find_closest(fiber, loc, tree, strandloc);
- verify_fiber_weights(fiber);
-
- strand_calc_root_distance(fiber, loc, nor, tang, strandloc);
+ if (BKE_mesh_sample_eval(scalp, &follicle->mesh_sample, loc, nor, tang)) {
+ hair_fiber_find_closest_strand(follicle, loc, tree, strandloc);
+ hair_fiber_verify_weights(follicle);
}
}
@@ -275,108 +336,3 @@ static void strands_calc_weights(const HairDrawDataInterface *hairdata, struct D
MEM_freeN(strandloc);
}
-HairFiber* BKE_hair_fibers_create(const HairDrawDataInterface *hairdata,
- struct DerivedMesh *scalp, unsigned int amount,
- unsigned int seed)
-{
- MeshSampleGenerator *gen = BKE_mesh_sample_gen_surface_random(scalp, seed);
- unsigned int i;
-
- HairFiber *fibers = MEM_mallocN(sizeof(HairFiber) * amount, "HairFiber");
- HairFiber *fiber;
-
- for (i = 0, fiber = fibers; i < amount; ++i, ++fiber) {
- if (BKE_mesh_sample_generate(gen, &fiber->root)) {
- int k;
- /* influencing control strands are determined later */
- for (k = 0; k < 4; ++k) {
- fiber->parent_index[k] = STRAND_INDEX_NONE;
- fiber->parent_weight[k] = 0.0f;
- }
- }
- else {
- /* clear remaining samples */
- memset(fiber, 0, sizeof(HairFiber) * (amount - i));
- break;
- }
- }
-
- BKE_mesh_sample_free_generator(gen);
-
- strands_calc_weights(hairdata, scalp, fibers, amount);
-
- return fibers;
-}
-#endif
-
-/* ================================= */
-
-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);
- hs
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list