[Bf-blender-cvs] [3b9a513] strand_gpu: Subdivision for strand fibers.
Lukas Tönne
noreply at git.blender.org
Thu Jul 7 20:35:20 CEST 2016
Commit: 3b9a5130683bf92ef4e19417c6b3c6d73260bb5d
Author: Lukas Tönne
Date: Thu Jul 7 20:33:46 2016 +0200
Branches: strand_gpu
https://developer.blender.org/rB3b9a5130683bf92ef4e19417c6b3c6d73260bb5d
Subdivision for strand fibers.
This is not supported for the edit mode fibers yet. Unifying the buffer creation
here would help a great deal.
===================================================================
M release/scripts/startup/bl_ui/properties_data_modifier.py
M source/blender/blenkernel/BKE_strands.h
M source/blender/blenkernel/intern/strands.c
M source/blender/makesdna/DNA_modifier_types.h
M source/blender/makesrna/intern/rna_modifier.c
M source/blender/modifiers/intern/MOD_strands.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 825dff4..679e5b1 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -891,6 +891,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.label(text="Display:")
col.prop(md, "show_strands", text="Control Strands")
col.prop(md, "show_fibers", text="Fibers")
+ col.prop(md, "subdivisions")
def SUBSURF(self, layout, ob, md):
layout.row().prop(md, "subdivision_type", expand=True)
diff --git a/source/blender/blenkernel/BKE_strands.h b/source/blender/blenkernel/BKE_strands.h
index f643535..f507d5a 100644
--- a/source/blender/blenkernel/BKE_strands.h
+++ b/source/blender/blenkernel/BKE_strands.h
@@ -96,8 +96,12 @@ typedef struct StrandData {
struct GPUDrawStrands *gpu_buffer;
} StrandData;
+int BKE_strand_data_numverts(int orig_num_verts, int subdiv);
+void BKE_strand_data_generate_verts(const struct StrandVertex *orig_verts, int orig_num_verts,
+ struct StrandVertexData *verts, float rootmat[4][4], int subdiv);
struct StrandData *BKE_strand_data_calc(struct Strands *strands, struct DerivedMesh *scalp,
- StrandFiber *fibers, int num_fibers);
+ StrandFiber *fibers, int num_fibers, int subdiv);
+
void BKE_strand_data_free(struct StrandData *data);
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/blenkernel/intern/strands.c b/source/blender/blenkernel/intern/strands.c
index 196638b..c745944 100644
--- a/source/blender/blenkernel/intern/strands.c
+++ b/source/blender/blenkernel/intern/strands.c
@@ -141,13 +141,63 @@ bool BKE_strands_get_fiber_matrix(const StrandFiber *fiber, DerivedMesh *root_dm
/* ------------------------------------------------------------------------- */
+int BKE_strand_data_numverts(int orig_num_verts, int subdiv)
+{
+ BLI_assert(orig_num_verts >= 2);
+ return (orig_num_verts - 1) * (1 << subdiv) + 1;
+}
+
+void BKE_strand_data_generate_verts(const StrandVertex *orig_verts, int orig_num_verts,
+ StrandVertexData *verts, float rootmat[4][4], int subdiv)
+{
+ /* initialize points */
+ {
+ const int step = (1 << subdiv);
+ int index = 0;
+ for (int k = 0; k < orig_num_verts; ++k, index += step) {
+ mul_v3_m4v3(verts[index].co, rootmat, orig_verts[k].co);
+ }
+ }
+
+ /* subdivide */
+ for (int d = 0; d < subdiv; ++d) {
+ const int num_edges = (orig_num_verts - 1) * (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].co, verts[index].co, verts[index + step].co);
+ mul_v3_fl(verts[index + hstep].co, 0.5f);
+ }
+
+ /* move original points */
+ index = step;
+ for (int k = 1; k < num_edges; ++k, index += step) {
+ add_v3_v3v3(verts[index].co, verts[index - hstep].co, verts[index + hstep].co);
+ mul_v3_fl(verts[index].co, 0.5f);
+ }
+ }
+}
+
+static int strand_data_count_totverts(Strands *strands, int subdiv)
+{
+ int totverts = 0;
+ int c;
+ StrandCurve *scurve = strands->curves;
+ for (c = 0; c < strands->totcurves; ++c, ++scurve)
+ totverts += BKE_strand_data_numverts(scurve->num_verts, subdiv);
+ return totverts;
+}
+
StrandData *BKE_strand_data_calc(Strands *strands, DerivedMesh *scalp,
- StrandFiber *fibers, int num_fibers)
+ StrandFiber *fibers, int num_fibers, int subdiv)
{
StrandData *data = MEM_callocN(sizeof(StrandData), "StrandData");
- data->totverts = strands->totverts;
data->totcurves = strands->totcurves;
+ data->totverts = strand_data_count_totverts(strands, subdiv);
data->totfibers = num_fibers;
data->verts = MEM_mallocN(sizeof(StrandVertexData) * data->totverts, "StrandVertexData");
data->curves = MEM_mallocN(sizeof(StrandCurveData) * data->totcurves, "StrandCurveData");
@@ -156,18 +206,18 @@ StrandData *BKE_strand_data_calc(Strands *strands, DerivedMesh *scalp,
int c;
StrandCurve *scurve = strands->curves;
StrandCurveData *curve = data->curves;
+ int verts_begin = 0;
for (c = 0; c < data->totcurves; ++c, ++scurve, ++curve) {
- curve->verts_begin = scurve->verts_begin;
- curve->num_verts = scurve->num_verts;
+ int num_verts = BKE_strand_data_numverts(scurve->num_verts, subdiv);
+ curve->verts_begin = verts_begin;
+ curve->num_verts = num_verts;
BKE_strands_get_matrix(scurve, scalp, curve->mat);
- int v;
- StrandVertex *svert = strands->verts + scurve->verts_begin;
- StrandVertexData *vert = data->verts + curve->verts_begin;
- for (v = 0; v < curve->num_verts; ++v, ++svert, ++vert) {
- mul_v3_m4v3(vert->co, curve->mat, svert->co);
- }
+ BKE_strand_data_generate_verts(strands->verts + scurve->verts_begin, scurve->num_verts,
+ data->verts + verts_begin, curve->mat, subdiv);
+
+ verts_begin += num_verts;
}
int i;
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index eeb1192..b086ac3 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1551,7 +1551,7 @@ typedef struct StrandsModifierData {
int flag;
int num_fibers;
int seed;
- int pad;
+ int subdiv;
struct Strands *strands;
struct StrandFiber *fibers;
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 33d2be3..89ddb62 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -4693,6 +4693,14 @@ static void rna_def_modifier_strands(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Fibers", "Number of rendered strand fibers to generate");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ prop = RNA_def_property(srna, "subdivisions", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "subdiv");
+ RNA_def_property_range(prop, 0, INT_MAX);
+ RNA_def_property_ui_range(prop, 0, 6, 1, 3);
+ RNA_def_property_int_default(prop, 2);
+ RNA_def_property_ui_text(prop, "Subdivisions", "Subdivisions for each segment of fibers");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop = RNA_def_property(srna, "show_strands", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_STRANDS_SHOW_STRANDS);
RNA_def_property_boolean_default(prop, true);
diff --git a/source/blender/modifiers/intern/MOD_strands.c b/source/blender/modifiers/intern/MOD_strands.c
index 3b50a6a..6f19e38 100644
--- a/source/blender/modifiers/intern/MOD_strands.c
+++ b/source/blender/modifiers/intern/MOD_strands.c
@@ -59,6 +59,7 @@ static void initData(ModifierData *md)
smd->num_fibers = 0;
smd->fibers = NULL;
+ smd->subdiv = 2;
smd->flag |= MOD_STRANDS_SHOW_STRANDS |
MOD_STRANDS_SHOW_FIBERS;
@@ -123,7 +124,9 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
if (smd->strands->data_final)
BKE_strand_data_free(smd->strands->data_final);
smd->strands->data_final = BKE_strand_data_calc(smd->strands, dm,
- smd->fibers, smd->fibers ? smd->num_fibers : 0);
+ smd->fibers,
+ smd->fibers ? smd->num_fibers : 0,
+ smd->subdiv);
if (smd->edit) {
/* clear draw data from edit when updating */
More information about the Bf-blender-cvs
mailing list