Commit: fec39ff862a4faaf490e5cc1b4148f7dc360f5b6
Author: Lukas Tönne
Date:   Mon Jun 25 07:37:44 2018 +0100
Branches: hair_guides_grooming
https://developer.blender.org/rBfec39ff862a4faaf490e5cc1b4148f7dc360f5b6

Function for generating guide curve vertices from groom data.

This should eventually allow re-sampling vertices add equal distances,
as well as allowing for additional deformation (e.g. curls).

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

M       source/blender/blenkernel/BKE_hair.h
M       source/blender/blenkernel/intern/groom.c

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

diff --git a/source/blender/blenkernel/BKE_hair.h 
b/source/blender/blenkernel/BKE_hair.h
index 73f8e3d9c12..adea3696893 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -55,6 +55,12 @@ void BKE_hair_free(struct HairSystem *hsys);
 
 /* === Guide Strands === */
 
+/* Allocate buffers for defining guide curves
+ * \param totcurves Number of guide curves to allocate
+ * \param totverts Number of guide curve vertices to allocate
+ */
+void BKE_hair_guide_curves_alloc(struct HairSystem *hsys, int totcurves, int 
totverts);
+
 /* Allocate buffers for defining guide curves
  * \param totcurves Number of guide curves to allocate
  */
diff --git a/source/blender/blenkernel/intern/groom.c 
b/source/blender/blenkernel/intern/groom.c
index bb992304581..704f2b25ad9 100644
--- a/source/blender/blenkernel/intern/groom.c
+++ b/source/blender/blenkernel/intern/groom.c
@@ -36,6 +36,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "BLI_array.h"
 #include "BLI_blenlib.h"
 #include "BLI_math.h"
 #include "BLI_utildefines.h"
@@ -859,6 +860,68 @@ void BKE_groom_hair_distribute(const Depsgraph *depsgraph, 
Groom *groom, unsigne
        }
 }
 
+typedef struct GroomGuideVertex
+{
+       int flag;
+       float co[3];
+} GroomGuideVertex;
+
+static void groom_guide_buffer_reserve(int reserve, GroomGuideVertex 
**r_verts, int *r_totalloc)
+{
+       if (reserve > *r_totalloc)
+       {
+               static const int blocksize = 1024;
+               int totalloc = (int)((reserve + blocksize - 1) / blocksize) * 
blocksize;
+               
+               *r_verts = MEM_reallocN_id(*r_verts, sizeof(**r_verts) * 
totalloc, __func__);
+               *r_totalloc = totalloc;
+       }
+}
+
+/* Generate vertices for the curve based on a guide function.
+ * The guide function maps 1D parametric space to a continuous 3D position and 
direction.
+ * 
+ * \param stepsize      Desired distance between guide curve vertices
+ * \param maxverts      Maximum number of allowed vertices
+ * \param r_verts       Array of vertices generated for the guide curve
+ * \param r_numverts    Reserved size of the vertex array
+ * \param r_numused     Number of vertices in the guide curve
+ */
+static void groom_guide_curve_discretize(
+        const GroomRegion *region,
+        int guide_idx,
+        float stepsize,
+        int maxverts,
+        GroomGuideVertex **r_verts,
+        int *r_totalloc,
+        int *r_totverts)
+{
+       const GroomBundle *bundle = &region->bundle;
+       const int shapesize = region->numverts;
+       const int curvesize = bundle->curvesize;
+       const float *weights = &bundle->guide_shape_weights[guide_idx * 
shapesize];
+
+       int totverts = *r_totverts;
+       for (int i = 0; i < curvesize; ++i)
+       {
+               if (*r_totverts < maxverts)
+               {
+                       totverts += 1;
+                       groom_guide_buffer_reserve(totverts, r_verts, 
r_totalloc);
+                       
+                       GroomGuideVertex *v = &((*r_verts)[totverts - 1]);
+                       /* Compute barycentric guide location from shape */
+                       zero_v3(v->co);
+                       for (int j = 0; j < shapesize; ++j)
+                       {
+                               madd_v3_v3fl(v->co, bundle->curvecache[j * 
curvesize + i].co, weights[j]);
+                       }
+                       v->flag = 0;
+               }
+       }
+       *r_totverts = totverts;
+}
+
 void BKE_groom_hair_update_guide_curves(const Depsgraph *depsgraph, Groom 
*groom)
 {
        struct HairSystem *hsys = groom->hair_system;
@@ -872,50 +935,64 @@ void BKE_groom_hair_update_guide_curves(const Depsgraph 
*depsgraph, Groom *groom
                totguides += bundle->totguides;
        }
        
-       /* First declare all guide curves and lengths */
-       BKE_hair_guide_curves_begin(hsys, totguides);
-       for (const GroomRegion *region = regions->first; region; region = 
region->next)
+       GroomGuideVertex *verts = NULL;
+       int totalloc = 0;
+       //groom_guide_buffer_reserve(totverts_est, &verts, &totalloc);
+       
+       int *numverts = MEM_callocN(sizeof(int) * totguides, __func__);
+       int totverts = 0;
+       // TODO multithreading here
        {
-               const GroomBundle *bundle = &region->bundle;
-               const int curvesize = bundle->curvesize;
-               for (int i = 0; i < bundle->totguides; ++i)
+               static const float stepsize = 0.01f;
+               static const int maxverts = 100000;
+               int guide_idx = 0;
+               for (const GroomRegion *region = regions->first; region; region 
= region->next)
                {
-                       /* TODO implement optional factors using scalp 
textures/vgroups */
-                       float taper_length = region->taper_length;
-                       float taper_thickness = region->taper_thickness;
-                       
-                       BKE_hair_set_guide_curve(hsys, i, 
&bundle->guides[i].root, curvesize,
-                                                taper_length, taper_thickness);
+                       const GroomBundle *bundle = &region->bundle;
+                       for (int i = 0; i < bundle->totguides; ++i)
+                       {
+                               const int prev_totverts = totverts;
+                               groom_guide_curve_discretize(region, i, 
stepsize, maxverts, &verts, &totalloc, &totverts);
+                               numverts[guide_idx] = totverts - prev_totverts;
+                               
+                               ++guide_idx;
+                       }
                }
        }
-       BKE_hair_guide_curves_end(hsys);
        
-       int idx = 0;
-       for (const GroomRegion *region = regions->first; region; region = 
region->next)
+       /* Declare all guide curves and lengths */
+       BKE_hair_guide_curves_begin(hsys, totguides);
        {
-               const GroomBundle *bundle = &region->bundle;
-               const int shapesize = region->numverts;
-               const int curvesize = bundle->curvesize;
-               const float *weights = bundle->guide_shape_weights;
-               float co[3];
-               for (int guide_idx = 0; guide_idx < bundle->totguides; 
++guide_idx)
+               int guide_idx = 0;
+               for (const GroomRegion *region = regions->first; region; region 
= region->next)
                {
-                       for (int j = 0; j < curvesize; ++j)
+                       const GroomBundle *bundle = &region->bundle;
+                       for (int i = 0; i < bundle->totguides; ++i)
                        {
-                               /* Compute barycentric guide location from 
shape */
-                               zero_v3(co);
-                               for (int k = 0; k < shapesize; ++k)
-                               {
-                                       madd_v3_v3fl(co, bundle->curvecache[k * 
curvesize + j].co, weights[k]);
-                               }
+                               /* TODO implement optional factors using scalp 
textures/vgroups */
+                               float taper_length = region->taper_length;
+                               float taper_thickness = region->taper_thickness;
                                
-                               BKE_hair_set_guide_vertex(hsys, idx, 0, co);
-                               ++idx;
+                               BKE_hair_set_guide_curve(
+                                           hsys,
+                                           i,
+                                           &bundle->guides[i].root,
+                                           numverts[guide_idx],
+                                           taper_length,
+                                           taper_thickness);
+                               ++guide_idx;
                        }
-                       
-                       weights += shapesize;
                }
        }
+       BKE_hair_guide_curves_end(hsys);
+       
+       for (int i = 0; i < totverts; ++i)
+       {
+               BKE_hair_set_guide_vertex(hsys, i, verts[i].flag, verts[i].co);
+       }
+       
+       MEM_freeN(numverts);
+       MEM_freeN(verts);
        
        const Mesh *scalp = BKE_groom_get_scalp(depsgraph, groom);
        if (scalp)

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to