Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern/groom.c')
-rw-r--r--source/blender/blenkernel/intern/groom.c64
1 files changed, 62 insertions, 2 deletions
diff --git a/source/blender/blenkernel/intern/groom.c b/source/blender/blenkernel/intern/groom.c
index eae4724f047..e64fd5ca297 100644
--- a/source/blender/blenkernel/intern/groom.c
+++ b/source/blender/blenkernel/intern/groom.c
@@ -495,8 +495,61 @@ void BKE_groom_bundle_unbind(GroomBundle *bundle)
/* === Hair System === */
-void BKE_groom_distribute_follicles(Groom *groom, unsigned int seed, int count)
+/* Distribute points on the scalp to use as guide curve origins,
+ * then interpolate guide curves from bundles
+ */
+static void groom_generate_guide_curves(
+ Groom *groom,
+ DerivedMesh *scalp,
+ unsigned int seed,
+ int guide_curve_count)
+{
+ struct HairSystem *hsys = groom->hair_system;
+
+ MeshSample *guide_samples = MEM_mallocN(sizeof(*guide_samples) * guide_curve_count, "guide samples");
+ int num_guides;
+ {
+ /* Random distribution of points on the scalp mesh */
+
+ float scalp_area = BKE_hair_calc_surface_area(scalp);
+ float density = BKE_hair_calc_density_from_count(scalp_area, guide_curve_count);
+ float min_distance = BKE_hair_calc_min_distance_from_density(density);
+ MeshSampleGenerator *gen = BKE_mesh_sample_gen_surface_poissondisk(
+ seed,
+ min_distance,
+ guide_curve_count,
+ NULL,
+ NULL);
+
+ BKE_mesh_sample_generator_bind(gen, scalp);
+
+ static const bool use_threads = false;
+ num_guides = BKE_mesh_sample_generate_batch_ex(
+ gen,
+ guide_samples,
+ sizeof(MeshSample),
+ guide_curve_count,
+ use_threads);
+
+ BKE_mesh_sample_free_generator(gen);
+ }
+
+ BKE_hair_guide_curves_begin(hsys, num_guides);
+
+ for (int i = 0; i < num_guides; ++i)
+ {
+ BKE_hair_set_guide_curve(hsys, i, &guide_samples[i], );
+ }
+
+ BKE_hair_guide_curves_end(hsys);
+
+ MEM_freeN(guide_samples);
+}
+
+void BKE_groom_hair_distribute(Groom *groom, unsigned int seed, int hair_count, int guide_curve_count)
{
+ struct HairSystem *hsys = groom->hair_system;
+
BLI_assert(groom->scalp_object);
DerivedMesh *scalp = object_get_derived_final(groom->scalp_object, false);
if (!scalp)
@@ -504,7 +557,10 @@ void BKE_groom_distribute_follicles(Groom *groom, unsigned int seed, int count)
return;
}
- BKE_hair_generate_follicles(groom->hair_system, scalp, seed, count);
+ BKE_hair_generate_follicles(hsys, scalp, seed, hair_count);
+
+ unsigned int guide_seed = BLI_ghashutil_combine_hash(seed, BLI_ghashutil_strhash("groom guide curves"));
+ groom_bundle_generate_guide_curves(groom, scalp, guide_seed, guide_curve_count);
}
@@ -768,8 +824,12 @@ void BKE_groom_eval_geometry(const EvaluationContext *UNUSED(eval_ctx), Groom *g
printf("%s on %s\n", __func__, groom->id.name);
}
+ /* calculate curves for interpolating shapes */
BKE_groom_curve_cache_update(groom);
+ /* generate actual guide curves for hair */
+ BKE_groom_hair_update_guide_curves(groom);
+
if (groom->bb == NULL || (groom->bb->flag & BOUNDBOX_DIRTY)) {
BKE_groom_boundbox_calc(groom, NULL, NULL);
}