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:
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py1
-rw-r--r--source/blender/blenkernel/BKE_editstrands.h10
-rw-r--r--source/blender/blenkernel/BKE_hair.h6
-rw-r--r--source/blender/blenkernel/intern/editstrands.c18
-rw-r--r--source/blender/blenkernel/intern/hair.c124
-rw-r--r--source/blender/blenkernel/intern/scene.c1
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c2
-rw-r--r--source/blender/draw/intern/draw_cache.c4
-rw-r--r--source/blender/draw/intern/draw_cache.h2
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h2
-rw-r--r--source/blender/draw/intern/draw_cache_impl_strands.c16
-rw-r--r--source/blender/makesdna/DNA_scene_types.h2
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c7
13 files changed, 141 insertions, 54 deletions
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 8056b14dc70..8a438cf9802 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -57,6 +57,7 @@ class VIEW3D_HT_header(Header):
row.prop(toolsettings.hair_edit, "hair_draw_mode", text="", expand=True)
if toolsettings.hair_edit.hair_draw_mode == 'FIBERS':
row.prop(toolsettings.hair_edit, "hair_draw_size", text="Size")
+ row.prop(toolsettings.hair_edit, "hair_draw_subdivision", text="Subdivide")
# Occlude geometry
if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or
diff --git a/source/blender/blenkernel/BKE_editstrands.h b/source/blender/blenkernel/BKE_editstrands.h
index e5858160f65..1e0ed8cf3c4 100644
--- a/source/blender/blenkernel/BKE_editstrands.h
+++ b/source/blender/blenkernel/BKE_editstrands.h
@@ -84,12 +84,10 @@ void BKE_editstrands_free(struct BMEditStrands *es);
bool BKE_editstrands_hair_ensure(struct BMEditStrands *es);
void BKE_editstrands_hair_free(struct BMEditStrands *es);
-int* BKE_editstrands_hair_get_fiber_lengths(struct BMEditStrands *es);
-void BKE_editstrands_hair_get_texture_buffer_size(struct BMEditStrands *es, int *r_size,
- int *r_strand_map_start,
- int *r_strand_vertex_start,
- int *r_fiber_start);
-void BKE_editstrands_hair_get_texture_buffer(struct BMEditStrands *es, void *texbuffer);
+int* BKE_editstrands_hair_get_fiber_lengths(struct BMEditStrands *es, int subdiv);
+void BKE_editstrands_hair_get_texture_buffer_size(struct BMEditStrands *es, int subdiv, int *r_size,
+ int *r_strand_map_start, int *r_strand_vertex_start, int *r_fiber_start);
+void BKE_editstrands_hair_get_texture_buffer(struct BMEditStrands *es, int subdiv, void *texbuffer);
/* === Constraints === */
diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index 5eafc14e66f..367741fb4fe 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -66,13 +66,13 @@ struct HairFiber* BKE_hair_fibers_create(const struct StrandsView *strands,
unsigned int seed);
int* BKE_hair_get_fiber_lengths(const struct HairFiber *fibers, int totfibers,
- const struct StrandsView *strands);
+ const struct StrandsView *strands, int subdiv);
-void BKE_hair_get_texture_buffer_size(const struct StrandsView *strands, int totfibers,
+void BKE_hair_get_texture_buffer_size(const struct StrandsView *strands, int totfibers, int subdiv,
int *r_size, int *r_strand_map_start,
int *r_strand_vertex_start, int *r_fiber_start);
void BKE_hair_get_texture_buffer(const struct StrandsView *strands, struct DerivedMesh *scalp,
- const struct HairFiber *fibers, int totfibers,
+ const struct HairFiber *fibers, int totfibers, int subdiv,
void *texbuffer);
#endif
diff --git a/source/blender/blenkernel/intern/editstrands.c b/source/blender/blenkernel/intern/editstrands.c
index 0fe286a5d3a..8cfc0bb606c 100644
--- a/source/blender/blenkernel/intern/editstrands.c
+++ b/source/blender/blenkernel/intern/editstrands.c
@@ -233,26 +233,24 @@ void BKE_editstrands_hair_free(BMEditStrands *es)
}
}
-int* BKE_editstrands_hair_get_fiber_lengths(BMEditStrands *es)
+int* BKE_editstrands_hair_get_fiber_lengths(BMEditStrands *es, int subdiv)
{
EditStrandsView strands = editstrands_get_view(es);
- return BKE_hair_get_fiber_lengths(es->hair_fibers, es->hair_totfibers, &strands.base);
+ return BKE_hair_get_fiber_lengths(es->hair_fibers, es->hair_totfibers, &strands.base, subdiv);
}
-void BKE_editstrands_hair_get_texture_buffer_size(BMEditStrands *es, int *r_size,
- int *r_strand_map_start,
- int *r_strand_vertex_start,
- int *r_fiber_start)
+void BKE_editstrands_hair_get_texture_buffer_size(BMEditStrands *es, int subdiv, int *r_size,
+ int *r_strand_map_start, int *r_strand_vertex_start, int *r_fiber_start)
{
EditStrandsView strands = editstrands_get_view(es);
- BKE_hair_get_texture_buffer_size(&strands.base, es->hair_totfibers,
- r_size, r_strand_map_start, r_strand_vertex_start, r_fiber_start);
+ BKE_hair_get_texture_buffer_size(&strands.base, es->hair_totfibers, subdiv, r_size,
+ r_strand_map_start, r_strand_vertex_start, r_fiber_start);
}
-void BKE_editstrands_hair_get_texture_buffer(BMEditStrands *es, void *texbuffer)
+void BKE_editstrands_hair_get_texture_buffer(BMEditStrands *es, int subdiv, void *texbuffer)
{
EditStrandsView strands = editstrands_get_view(es);
- BKE_hair_get_texture_buffer(&strands.base, es->root_dm, es->hair_fibers, es->hair_totfibers, texbuffer);
+ BKE_hair_get_texture_buffer(&strands.base, es->root_dm, es->hair_fibers, es->hair_totfibers, subdiv, texbuffer);
}
/* === Constraints === */
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 59677a25bc1..ee02d92c193 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -256,13 +256,26 @@ HairFiber* BKE_hair_fibers_create(const StrandsView *strands,
return fibers;
}
-int* BKE_hair_get_fiber_lengths(const HairFiber *fibers, int totfibers, const StrandsView *strands)
+static int hair_get_strand_subdiv_numverts(int numstrands, int numverts, int subdiv)
+{
+ return ((numverts - numstrands) << subdiv) + numstrands;
+}
+
+static void hair_get_strand_subdiv_lengths(int *lengths, const int *orig_lengths, int num_strands, int subdiv)
+{
+ for (int i = 0; i < num_strands; ++i) {
+ lengths[i] = ((orig_lengths[i] - 1) << subdiv) + 1;
+ }
+}
+
+int* BKE_hair_get_fiber_lengths(const HairFiber *fibers, int totfibers, const StrandsView *strands, int subdiv)
{
int *fiber_length = MEM_mallocN(sizeof(int) * totfibers, "fiber length");
const int num_strands = strands->get_num_strands(strands);
- int *strand_length = MEM_mallocN(sizeof(int) * num_strands, "strand length");
- strands->get_strand_lengths(strands, strand_length);
+ int *lengths = MEM_mallocN(sizeof(int) * num_strands, "strand length");
+ strands->get_strand_lengths(strands, lengths);
+ hair_get_strand_subdiv_lengths(lengths, lengths, num_strands, subdiv);
for (int i = 0; i < totfibers; ++i) {
@@ -276,14 +289,14 @@ int* BKE_hair_get_fiber_lengths(const HairFiber *fibers, int totfibers, const St
}
BLI_assert(si < num_strands);
- fiblen += (float)strand_length[si] * sw;
+ fiblen += (float)lengths[si] * sw;
}
// use rounded number of segments
fiber_length[i] = (int)(fiblen + 0.5f);
}
- MEM_freeN(strand_length);
+ MEM_freeN(lengths);
return fiber_length;
}
@@ -328,8 +341,8 @@ static void hair_strand_transport_frame(const float co1[3], const float co2[3],
copy_v3_v3(prev_nor, r_nor);
}
-static void hair_strand_calc_verts(const float (*positions)[3], int num_verts, float rootmat[3][3],
- HairStrandVertexTextureBuffer *strand)
+static void hair_strand_calc_vectors(const float (*positions)[3], int num_verts, float rootmat[3][3],
+ HairStrandVertexTextureBuffer *strand)
{
for (int i = 0; i < num_verts; ++i) {
copy_v3_v3(strand[i].co, positions[i]);
@@ -360,6 +373,50 @@ static void hair_strand_calc_verts(const float (*positions)[3], int num_verts, f
}
}
+static int hair_strand_subdivide(float (*verts)[3], const float (*verts_orig)[3], int numverts_orig, int subdiv)
+{
+ {
+ /* Move vertex positions from the dense array to their initial configuration for subdivision. */
+ const int step = (1 << subdiv);
+ const float (*src)[3] = verts_orig;
+ float (*dst)[3] = verts;
+ for (int i = 0; i < numverts_orig; ++i) {
+ copy_v3_v3(*dst, *src);
+
+ ++src;
+ dst += step;
+ }
+ }
+
+ /* Subdivide */
+ for (int d = 0; d < subdiv; ++d) {
+ const int num_edges = (numverts_orig - 1) << d;
+ const int hstep = 1 << (subdiv - d - 1);
+ const int step = 1 << (subdiv - d);
+
+ /* Calculate edge points */
+ {
+ int index = 0;
+ for (int k = 0; k < num_edges; ++k, index += step) {
+ add_v3_v3v3(verts[index + hstep], verts[index], verts[index + step]);
+ mul_v3_fl(verts[index + hstep], 0.5f);
+ }
+ }
+
+ /* Move original points */
+ {
+ int index = step;
+ for (int k = 1; k < num_edges; ++k, index += step) {
+ add_v3_v3v3(verts[index], verts[index - hstep], verts[index + hstep]);
+ mul_v3_fl(verts[index], 0.5f);
+ }
+ }
+ }
+
+ const int num_verts = ((numverts_orig - 1) << subdiv) + 1;
+ return num_verts;
+}
+
static void hair_get_fiber_buffer(const HairFiber *fibers, int totfibers, DerivedMesh *scalp,
HairFiberTextureBuffer *fiber_buf)
{
@@ -374,60 +431,85 @@ static void hair_get_fiber_buffer(const HairFiber *fibers, int totfibers, Derive
}
}
-void BKE_hair_get_texture_buffer_size(const StrandsView *strands, int totfibers,
+void BKE_hair_get_texture_buffer_size(const StrandsView *strands, int totfibers, int subdiv,
int *r_size, int *r_strand_map_start,
int *r_strand_vertex_start, int *r_fiber_start)
{
const int totstrands = strands->get_num_strands(strands);
const int totverts = strands->get_num_verts(strands);
+ const int totverts_subdiv = hair_get_strand_subdiv_numverts(totstrands, totverts, subdiv);
*r_strand_map_start = 0;
*r_strand_vertex_start = *r_strand_map_start + totstrands * sizeof(HairStrandMapTextureBuffer);
- *r_fiber_start = *r_strand_vertex_start + totverts * sizeof(HairStrandVertexTextureBuffer);
+ *r_fiber_start = *r_strand_vertex_start + totverts_subdiv * sizeof(HairStrandVertexTextureBuffer);
*r_size = *r_fiber_start + totfibers * sizeof(HairFiberTextureBuffer);
}
void BKE_hair_get_texture_buffer(const StrandsView *strands, DerivedMesh *scalp,
- const HairFiber *fibers, int totfibers,
+ const HairFiber *fibers, int totfibers, int subdiv,
void *buffer)
{
const int totstrands = strands->get_num_strands(strands);
- const int totverts = strands->get_num_verts(strands);
+ const int totverts_orig = strands->get_num_verts(strands);
+ const int totverts = hair_get_strand_subdiv_numverts(totstrands, totverts_orig, subdiv);
const int strand_map_start = 0;
const int strand_vertex_start = strand_map_start + totstrands * sizeof(HairStrandMapTextureBuffer);
const int fiber_start = strand_vertex_start + totverts * sizeof(HairStrandVertexTextureBuffer);
- int *lengths = MEM_mallocN(sizeof(int) * totstrands, "strand lengths");
+ int *lengths_orig = MEM_mallocN(sizeof(int) * totstrands, "strand lengths");
+ float (*positions_orig)[3] = MEM_mallocN(sizeof(float[3]) * totverts_orig, "strand vertex positions");
MeshSample *roots = MEM_mallocN(sizeof(MeshSample) * totstrands, "strand roots");
- float (*positions)[3] = MEM_mallocN(sizeof(float[3]) * totverts, "strand vertex positions");
-
- strands->get_strand_lengths(strands, lengths);
+ strands->get_strand_lengths(strands, lengths_orig);
+ strands->get_strand_vertices(strands, positions_orig);
strands->get_strand_roots(strands, roots);
- strands->get_strand_vertices(strands, positions);
+
+ int *lengths;
+ float (*positions)[3];
+ if (subdiv > 0) {
+ lengths = MEM_mallocN(sizeof(int) * totstrands, "strand lengths subdivided");
+ hair_get_strand_subdiv_lengths(lengths, lengths_orig, totstrands, subdiv);
+
+ positions = MEM_mallocN(sizeof(float[3]) * totverts, "strand vertex positions subdivided");
+ }
+ else {
+ lengths = lengths_orig;
+ positions = positions_orig;
+ }
HairStrandMapTextureBuffer *smap = (HairStrandMapTextureBuffer*)((char*)buffer + strand_map_start);
HairStrandVertexTextureBuffer *svert = (HairStrandVertexTextureBuffer*)((char*)buffer + strand_vertex_start);
- unsigned int vertex_start = 0;
+ int vertex_orig_start = 0;
+ int vertex_start = 0;
for (int i = 0; i < totstrands; ++i) {
- const unsigned int len = lengths[i];
+ const int len_orig = lengths_orig[i];
+ const int len = lengths[i];
smap->vertex_start = vertex_start;
smap->vertex_count = len;
+ if (subdiv > 0) {
+ hair_strand_subdivide(positions + vertex_start, positions_orig + vertex_orig_start, len_orig, subdiv);
+ }
+
{
float pos[3];
float matrix[3][3];
BKE_mesh_sample_eval(scalp, &roots[i], pos, matrix[2], matrix[0]);
cross_v3_v3v3(matrix[1], matrix[2], matrix[0]);
- hair_strand_calc_verts(positions + vertex_start, len, matrix, svert);
+ hair_strand_calc_vectors(positions + vertex_start, len, matrix, svert);
}
+ vertex_orig_start += len_orig;
vertex_start += len;
++smap;
svert += len;
}
- MEM_freeN(lengths);
+ MEM_freeN(lengths_orig);
+ MEM_freeN(positions_orig);
MEM_freeN(roots);
- MEM_freeN(positions);
+ if (subdiv > 0) {
+ MEM_freeN(lengths);
+ MEM_freeN(positions);
+ }
hair_get_fiber_buffer(fibers, totfibers, scalp, (HairFiberTextureBuffer*)((char*)buffer + fiber_start));
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index e2fcef83abb..eada47fbb5f 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -802,6 +802,7 @@ void BKE_scene_init(Scene *sce)
sce->toolsettings->hair_edit.select_mode = HAIR_SELECT_VERTEX;
sce->toolsettings->hair_edit.hair_draw_mode = HAIR_DRAW_FIBERS;
sce->toolsettings->hair_edit.hair_draw_size = 2.5f;
+ sce->toolsettings->hair_edit.hair_draw_subdiv = 2;
sce->physics_settings.gravity[0] = 0.0f;
sce->physics_settings.gravity[1] = 0.0f;
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index a50b5b62e62..9772666d3ae 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -1136,7 +1136,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata, EEVEE_SceneLayerData *sl
use_fibers = true;
copy_m4_m4(mat, ob->obmat);
- hair_geom = DRW_cache_editstrands_get_hair_fibers(edit, true, &fiber_buffer);
+ hair_geom = DRW_cache_editstrands_get_hair_fibers(edit, true, tsettings->hair_draw_subdiv, &fiber_buffer);
if (!edit->texture) {
edit->texture = DRW_texture_create_2D(fiber_buffer->width, fiber_buffer->height,
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index f2772c47d67..a4753c9b55b 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -2610,8 +2610,8 @@ Gwn_Batch *DRW_cache_editstrands_get_wires(struct BMEditStrands *es)
return DRW_editstrands_batch_cache_get_wires(es);
}
-Gwn_Batch *DRW_cache_editstrands_get_hair_fibers(struct BMEditStrands *es, bool use_ribbons,
+Gwn_Batch *DRW_cache_editstrands_get_hair_fibers(struct BMEditStrands *es, bool use_ribbons, int subdiv,
const struct DRWHairFiberTextureBuffer **r_buffer)
{
- return DRW_editstrands_batch_cache_get_hair_fibers(es, use_ribbons, r_buffer);
+ return DRW_editstrands_batch_cache_get_hair_fibers(es, use_ribbons, subdiv, r_buffer);
}
diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h
index ebf4dbafe2c..c536bd81084 100644
--- a/source/blender/draw/intern/draw_cache.h
+++ b/source/blender/draw/intern/draw_cache.h
@@ -164,7 +164,7 @@ struct Gwn_Batch *DRW_cache_editstrands_get_roots(struct BMEditStrands *es);
struct Gwn_Batch *DRW_cache_editstrands_get_points(struct BMEditStrands *es);
struct Gwn_Batch *DRW_cache_editstrands_get_wires(struct BMEditStrands *es);
-struct Gwn_Batch *DRW_cache_editstrands_get_hair_fibers(struct BMEditStrands *es, bool use_ribbons,
+struct Gwn_Batch *DRW_cache_editstrands_get_hair_fibers(struct BMEditStrands *es, bool use_ribbons, int subdiv,
const struct DRWHairFiberTextureBuffer **r_buffer);
#endif /* __DRAW_CACHE_H__ */
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 9c1ad374de1..a6f4c486e2f 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -112,7 +112,7 @@ struct Gwn_Batch *DRW_editstrands_batch_cache_get_wires(struct BMEditStrands *es
struct Gwn_Batch *DRW_editstrands_batch_cache_get_tips(struct BMEditStrands *es);
struct Gwn_Batch *DRW_editstrands_batch_cache_get_roots(struct BMEditStrands *es);
struct Gwn_Batch *DRW_editstrands_batch_cache_get_points(struct BMEditStrands *es);
-struct Gwn_Batch *DRW_editstrands_batch_cache_get_hair_fibers(struct BMEditStrands *es, bool use_ribbons,
+struct Gwn_Batch *DRW_editstrands_batch_cache_get_hair_fibers(struct BMEditStrands *es, bool use_ribbons, int subdiv,
const struct DRWHairFiberTextureBuffer **r_buffer);
#endif /* __DRAW_CACHE_IMPL_H__ */
diff --git a/source/blender/draw/intern/draw_cache_impl_strands.c b/source/blender/draw/intern/draw_cache_impl_strands.c
index 2d57d7e20ac..d3e9406fcfb 100644
--- a/source/blender/draw/intern/draw_cache_impl_strands.c
+++ b/source/blender/draw/intern/draw_cache_impl_strands.c
@@ -364,12 +364,12 @@ Gwn_Batch *DRW_editstrands_batch_cache_get_points(BMEditStrands *es)
return cache->points;
}
-static void editstrands_batch_cache_ensure_hair_fibers(BMEditStrands *es, StrandsBatchCache *cache, bool use_ribbons)
+static void editstrands_batch_cache_ensure_hair_fibers(BMEditStrands *es, StrandsBatchCache *cache, bool use_ribbons, int subdiv)
{
GWN_VERTBUF_DISCARD_SAFE(cache->hair.verts);
GWN_INDEXBUF_DISCARD_SAFE(cache->hair.segments);
- int *fiber_lengths = BKE_editstrands_hair_get_fiber_lengths(es);
+ int *fiber_lengths = BKE_editstrands_hair_get_fiber_lengths(es, subdiv);
int totpoint = 0;
for (int i = 0; i < es->hair_totfibers; ++i) {
totpoint += fiber_lengths[i];
@@ -446,7 +446,7 @@ static void editstrands_batch_cache_ensure_hair_fibers(BMEditStrands *es, Strand
cache->hair.segments = GWN_indexbuf_build(&elb);
}
-static void editstrands_batch_cache_ensure_hair_fiber_texbuffer(BMEditStrands *es, StrandsBatchCache *cache, bool UNUSED(use_ribbons))
+static void editstrands_batch_cache_ensure_hair_fiber_texbuffer(BMEditStrands *es, StrandsBatchCache *cache, bool UNUSED(use_ribbons), int subdiv)
{
DRWHairFiberTextureBuffer *buffer = &cache->hair.texbuffer;
static const int elemsize = 8;
@@ -455,7 +455,7 @@ static void editstrands_batch_cache_ensure_hair_fiber_texbuffer(BMEditStrands *e
// Offsets in bytes
int b_size, b_strand_map_start, b_strand_vertex_start, b_fiber_start;
- BKE_editstrands_hair_get_texture_buffer_size(es, &b_size,
+ BKE_editstrands_hair_get_texture_buffer_size(es, subdiv, &b_size,
&b_strand_map_start, &b_strand_vertex_start, &b_fiber_start);
// Pad for alignment
b_size += align - b_size % align;
@@ -465,7 +465,7 @@ static void editstrands_batch_cache_ensure_hair_fiber_texbuffer(BMEditStrands *e
const int height = size / width;
buffer->data = MEM_mallocN(b_size, "hair fiber texture buffer");
- BKE_editstrands_hair_get_texture_buffer(es, buffer->data);
+ BKE_editstrands_hair_get_texture_buffer(es, subdiv, buffer->data);
buffer->width = width;
buffer->height = height;
@@ -474,7 +474,7 @@ static void editstrands_batch_cache_ensure_hair_fiber_texbuffer(BMEditStrands *e
buffer->fiber_start = b_fiber_start / elemsize;
}
-Gwn_Batch *DRW_editstrands_batch_cache_get_hair_fibers(BMEditStrands *es, bool use_ribbons,
+Gwn_Batch *DRW_editstrands_batch_cache_get_hair_fibers(BMEditStrands *es, bool use_ribbons, int subdiv,
const DRWHairFiberTextureBuffer **r_buffer)
{
StrandsBatchCache *cache = editstrands_batch_cache_get(es);
@@ -484,13 +484,13 @@ Gwn_Batch *DRW_editstrands_batch_cache_get_hair_fibers(BMEditStrands *es, bool u
}
if (cache->hair.fibers == NULL) {
- editstrands_batch_cache_ensure_hair_fibers(es, cache, use_ribbons);
+ editstrands_batch_cache_ensure_hair_fibers(es, cache, use_ribbons, subdiv);
Gwn_PrimType prim_type = use_ribbons ? GWN_PRIM_TRIS : GWN_PRIM_LINES;
cache->hair.fibers = GWN_batch_create(prim_type, cache->hair.verts, cache->hair.segments);
cache->hair.use_ribbons = use_ribbons;
- editstrands_batch_cache_ensure_hair_fiber_texbuffer(es, cache, use_ribbons);
+ editstrands_batch_cache_ensure_hair_fiber_texbuffer(es, cache, use_ribbons, subdiv);
}
if (r_buffer) {
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index b73c1aa63a6..83747527432 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -1145,7 +1145,7 @@ typedef struct HairEditSettings {
short select_mode;
short hair_draw_mode;
float hair_draw_size;
- int pad;
+ int hair_draw_subdiv;
struct Brush *brush;
struct Object *shape_object;
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 83c47be3496..b72e88cd79f 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -1206,6 +1206,13 @@ static void rna_def_hair_edit(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Hair Draw Size", "Width of hair fibers in pixels");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_HairEdit_update");
+ prop = RNA_def_property(srna, "hair_draw_subdivision", PROP_INT, PROP_NONE);
+ RNA_def_property_int_sdna(prop, NULL, "hair_draw_subdiv");
+ RNA_def_property_range(prop, 0, INT_MAX);
+ RNA_def_property_ui_range(prop, 0, 5, 1, -1);
+ RNA_def_property_ui_text(prop, "Hair Draw Subdivision", "Subdivide hair fibers");
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_HairEdit_update");
+
prop = RNA_def_property(srna, "shape_object", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Shape Object", "Outer shape to use for tools");