Commit: c0c8df3f2cf3ab03cec1f660619b0fe2290caf2a
Author: Lukas Tönne
Date:   Sun Apr 15 09:30:15 2018 +0100
Branches: hair_guides
https://developer.blender.org/rBc0c8df3f2cf3ab03cec1f660619b0fe2290caf2a

Initial system for generating guide curves from groom.

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

M       source/blender/blenkernel/BKE_groom.h
M       source/blender/blenkernel/BKE_hair.h
M       source/blender/blenkernel/intern/groom.c
M       source/blender/blenkernel/intern/hair.c
M       source/blender/editors/groom/groom_hair.c
M       source/blender/editors/object/object_modifier.c
M       source/blender/makesdna/DNA_hair_types.h

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

diff --git a/source/blender/blenkernel/BKE_groom.h 
b/source/blender/blenkernel/BKE_groom.h
index aa5b9fb53a0..e88513b5480 100644
--- a/source/blender/blenkernel/BKE_groom.h
+++ b/source/blender/blenkernel/BKE_groom.h
@@ -71,7 +71,11 @@ void BKE_groom_bundle_unbind(struct GroomBundle *bundle);
 
 /* === Hair System === */
 
-void BKE_groom_distribute_follicles(struct Groom *groom, unsigned int seed, 
int count);
+/* Create follicles and guide curve origins on the scalp surface for hair 
fiber rendering */
+void BKE_groom_hair_distribute(struct Groom *groom, unsigned int seed, int 
hair_count, int guide_curve_count);
+
+/* Calculate guide curve shapes based on groom bundle deformation */
+void BKE_groom_hair_update_guide_curves(struct Groom *groom);
 
 
 /* === Depsgraph evaluation === */
diff --git a/source/blender/blenkernel/BKE_hair.h 
b/source/blender/blenkernel/BKE_hair.h
index 42a09dd756a..01e4d3e0abe 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -53,11 +53,28 @@ void BKE_hair_free(struct HairSystem *hsys);
 
 /* === Guide Strands === */
 
-void BKE_hair_guide_curves_begin(struct HairSystem *hsys, int totcurves, int 
totverts);
+/* Allocate buffers for defining guide curves
+ * \param totcurves Number of guide curves to allocate
+ */
+void BKE_hair_guide_curves_begin(struct HairSystem *hsys, int totcurves);
+
+/* Set properties of a guide curve
+ * \param index Index of the guide guide curve
+ * \param mesh_sample Origin of the guide curve on the scalp mesh.
+ * \param numverts Number of vertices in this guide curve
+ */
 void BKE_hair_set_guide_curve(struct HairSystem *hsys, int index, const struct 
MeshSample *mesh_sample, int numverts);
-void BKE_hair_set_guide_vertex(struct HairSystem *hsys, int index, int flag, 
const float co[3]);
+
+/* Finalize guide curve update */
 void BKE_hair_guide_curves_end(struct HairSystem *hsys);
 
+/* Set properties of a guide curve vertex
+ * \param index Index of the guide curve vertex.
+ * \param flag Flags to set on the vertex.
+ * \param co Location of the vertex in object space.
+ */
+void BKE_hair_set_guide_vertex(struct HairSystem *hsys, int index, int flag, 
const float co[3]);
+
 /* === Follicles === */
 
 /* Calculate surface area of a scalp mesh */
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);
        }
diff --git a/source/blender/blenkernel/intern/hair.c 
b/source/blender/blenkernel/intern/hair.c
index 588bd167f41..5a9af8aba58 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -204,21 +204,14 @@ void BKE_hair_generate_follicles(
 
 /* ================================= */
 
-void BKE_hair_guide_curves_begin(HairSystem *hsys, int totcurves, int totverts)
+void BKE_hair_guide_curves_begin(HairSystem *hsys, int totcurves)
 {
        if (totcurves != hsys->totcurves)
        {
                hsys->curves = MEM_reallocN(hsys->curves, 
sizeof(HairGuideCurve) * totcurves);
                hsys->totcurves = totcurves;
 
-               hsys->flag |= HAIR_SYSTEM_UPDATE_GUIDE_VERT_OFFSET | 
HAIR_SYSTEM_UPDATE_FOLLICLE_BINDING;
-               BKE_hair_batch_cache_dirty(hsys, BKE_HAIR_BATCH_DIRTY_ALL);
-       }
-       if (totverts != hsys->totverts)
-       {
-               hsys->verts = MEM_reallocN(hsys->verts, sizeof(HairGuideVertex) 
* totverts);
-               hsys->totverts = totverts;
-
+               hsys->flag |= HAIR_SYSTEM_UPDATE_FOLLICLE_BINDING;
                BKE_hair_batch_cache_dirty(hsys, BKE_HAIR_BATCH_DIRTY_ALL);
        }
 }
@@ -231,10 +224,29 @@ void BKE_hair_set_guide_curve(HairSystem *hsys, int 
index, const MeshSample *mes
        memcpy(&curve->mesh_sample, mesh_sample, sizeof(MeshSample));
        curve->numverts = numverts;
        
-       hsys->flag |= HAIR_SYSTEM_UPDATE_GUIDE_VERT_OFFSET | 
HAIR_SYSTEM_UPDATE_FOLLICLE_BINDING;
+       hsys->flag |= HAIR_SYSTEM_UPDATE_FOLLICLE_BINDING;
        BKE_hair_batch_cache_dirty(hsys, BKE_HAIR_BATCH_DIRTY_ALL);
 }
 
+void BKE_hair_guide_curves_end(HairSystem *hsys)
+{
+       /* Recalculate vertex count and start offsets in curves */
+       int vertstart = 0;
+       for (int i = 0; i < hsys->totcurves; ++i)
+       {
+               hsys->curves[i].vertstart = vertstart;
+               vertstart += hsys->curves[i].numverts;
+       }
+
+       if (vertstart != hsys->totverts)
+       {
+               hsys->verts = MEM_reallocN(hsys->verts, sizeof(HairGuideVertex) 
* vertstart);
+               hsys->totverts = vertstart;
+
+               BKE_hair_batch_cache_dirty(hsys, BKE_HAIR_BATCH_DIRTY_ALL);
+       }
+}
+
 void BKE_hair_set_guide_vertex(HairSystem *hsys, int index, int flag, const 
float co[3])
 {
        BLI_assert(index <= hsys->totverts);
@@ -246,23 +258,6 @@ void BKE_hair_set_guide_vertex(HairSystem *hsys, int 
index, int flag, const floa
        BKE_hair_batch_cache_dirty(hsys, BKE_HAIR_BATCH_DIRTY_ALL);
 }
 
-void BKE_hair_guide_curves_end(HairSystem *hsys)
-{
-       /* Recalculate vertex offsets */
-       if (!(hsys->flag & HAIR_SYSTEM_UPDATE_GUIDE_VERT_OFFSET))
-       {
-               return;
-       }
-       hsys->flag &= ~HAIR_SYSTEM_UPDATE_GUIDE_VERT_OFFSET;
-       
-       int vertstart = 0;
-       for (int i = 0; i < hsys->totcurves; ++i)
-       {
-               hsys->curves[i].vertstart = vertstart;
-               vertstart += hsys->curves[i].numverts;
-       }
-}
-
 /* ================================= */
 
 BLI_INLINE void hair_fiber_verify_weights(HairFollicle *follicle)
diff --git a/source/blender/editors/groom/groom_hair.c 
b/source/blender/editors/groom/groom_hair.c
index 22664361639..0a179a9b20e 100644
--- a/source/blender/editors/groom/groom_hair.c
+++ b/source/blender/editors/groom/groom_hair.c
@@ -72,7 +72,8 @@ static int hair_distribute_exec(bContext *C, wmOperator *op)
 {
        Object *ob = ED_object_context(C);
        Groom *groom = ob->data;
-       int count = RNA_int_get(op->ptr, "count");
+       int hair_count = RNA_int_get(op->ptr, "hair_count");
+       int guide_curve_count = RNA_int_get(op->ptr, "guide_curve_count");
        unsigned int seed = (unsigned int)RNA_int_get(op->ptr, "seed");
 
        if (!groom->scalp_object)
@@ -81,7 +82,7 @@ static int hair_distribute_exec(bContext *C, wmOperator *op)
                return OPERATOR_CANCELLED;
        }
 
-       BKE_groom_distribute_follicles(groom, seed, count);
+       BKE_groom_hair_distribute(groom, seed, hair_count, guide_curve_count);
 
        WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
        DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -104,8 +105,10 @@ void GROOM_OT_hair_distribute(wmOperatorType *ot)
        /* flags */
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 
-       RNA_def_int(ot->srna, "count", 1000, 0, INT_MAX,
-                   "Count", "Number of follicles to generate", 1, 1e6);
+       RNA_def_int(ot->srna, "hair_count", 1000, 0, INT_MAX,
+                   "Hair Count", "Number of hairs to generate", 1, 1e6);
+       RNA_def_int(ot->srna, "guide_curve_count", 10, 0, INT_MAX,
+                   "Guide Curve Count", "Number of guide curves to generate", 
1, 1e4);
        RNA_def_int(ot->srna, "seed", 0, 0, INT_MAX,
                    "Seed", "Seed value for randomized follicle distribution", 
0, INT_MAX);
 }
diff --git a/source/blender/editors/object/object_modifier.c 
b/source/blender/editors/object/object_modifier.c
index bd88330498a..2099ceaa10b 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -2387,29 +2387,34 @@ static void fur_create_guide_curves(struct HairSystem 
*hsys, unsigned int seed,
        {
                MeshSample *buffer = MEM_mallocN(sizeof

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to