[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