[Bf-blender-cvs] [bbe11e3] strand_gpu: Unified buffer creation for drawing strands in object and edit mode.

Lukas Tönne noreply at git.blender.org
Fri Jul 8 16:25:26 CEST 2016


Commit: bbe11e39492db63d87305bcfbe157f7efda73179
Author: Lukas Tönne
Date:   Fri Jul 8 13:29:17 2016 +0200
Branches: strand_gpu
https://developer.blender.org/rBbbe11e39492db63d87305bcfbe157f7efda73179

Unified buffer creation for drawing strands in object and edit mode.

Control strands are now drawn without subdivision. Control and fiber
strands get their own vertex buffers for this purpose.

The intermediate StrandData has been removed, because it is just
redundant storage of the draw data buffers. The results in StrandData
are not used for further editing, so there is really no point in
keeping them around.

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

M	source/blender/blenkernel/BKE_editstrands.h
M	source/blender/blenkernel/BKE_strands.h
M	source/blender/blenkernel/intern/editstrands.c
M	source/blender/blenkernel/intern/strands.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/editors/hair/hair_object_strands.c
M	source/blender/editors/hair/hair_undo.c
M	source/blender/editors/object/object_strands.c
M	source/blender/editors/space_view3d/drawobject.c
M	source/blender/editors/space_view3d/drawstrands.c
M	source/blender/editors/space_view3d/view3d_intern.h
M	source/blender/gpu/GPU_buffers.h
M	source/blender/gpu/intern/gpu_buffers.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesdna/DNA_strand_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_strands.c

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

diff --git a/source/blender/blenkernel/BKE_editstrands.h b/source/blender/blenkernel/BKE_editstrands.h
index 4b21104..49037d8 100644
--- a/source/blender/blenkernel/BKE_editstrands.h
+++ b/source/blender/blenkernel/BKE_editstrands.h
@@ -55,11 +55,9 @@ typedef struct BMEditStrands {
 	struct StrandFiber *fibers;
 	/* Scalp mesh for fixing root vertices */
 	struct DerivedMesh *root_dm;
-	int num_fibers;
+	int totfibers;
 	
 	int flag;
-	
-	struct GPUDrawStrands *gpu_buffer;
 } BMEditStrands;
 
 /* BMEditStrands->flag */
@@ -74,8 +72,6 @@ struct BMEditStrands *BKE_editstrands_from_object(struct Object *ob);
 void BKE_editstrands_update_linked_customdata(struct BMEditStrands *es);
 void BKE_editstrands_free(struct BMEditStrands *es);
 
-void BKE_editstrands_clear_drawdata(struct BMEditStrands *es);
-
 /* === constraints === */
 
 /* Stores vertex locations for temporary reference:
diff --git a/source/blender/blenkernel/BKE_strands.h b/source/blender/blenkernel/BKE_strands.h
index f507d5a..680c576 100644
--- a/source/blender/blenkernel/BKE_strands.h
+++ b/source/blender/blenkernel/BKE_strands.h
@@ -36,8 +36,11 @@
 
 #include "DNA_strand_types.h"
 
+struct BMesh;
+struct BMVert;
 struct DerivedMesh;
 struct GPUStrandsShader;
+struct GPUDrawStrands;
 
 static const unsigned int STRAND_INDEX_NONE = 0xFFFFFFFF;
 
@@ -53,56 +56,20 @@ bool BKE_strands_get_fiber_matrix(const struct StrandFiber *fiber, struct Derive
 
 /* ------------------------------------------------------------------------- */
 
-typedef struct StrandVertexData {
-	/* Position */
-	float co[3];
-	int pad;
-} StrandVertexData;
-
-typedef struct StrandCurveData {
-	/* Start of vertex list */
-	unsigned int verts_begin;
-	/* Number of vertices in the curve */
-	unsigned int num_verts;
-	
-	/* Transform from strand space to object space */
-	float mat[4][4];
-} StrandCurveData;
-
-typedef struct StrandFiberData {
-	/* Position */
-	float co[3];
-	/* Indices of control strands for interpolation */
-	unsigned int control_index[4];
-	/* Weights of control strands for interpolation */
-	float control_weight[4];
-} StrandFiberData;
-
-typedef struct StrandData {
-	/* Array of vertices */
-	StrandVertexData *verts;
-	/* Array of curves */
-	StrandCurveData *curves;
-	/* Array of fibers */
-	StrandFiberData *fibers;
-	
-	/* Total number of vertices */
-	int totverts;
-	/* Total number of curves */
-	int totcurves;
-	/* Total number of fibers */
-	int totfibers;
-	
-	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, int subdiv);
-
-void BKE_strand_data_free(struct StrandData *data);
+typedef struct StrandCurveCache {
+	float (*verts)[3];
+	int maxverts;
+} StrandCurveCache;
+
+struct StrandCurveCache *BKE_strand_curve_cache_create(const struct Strands *strands, int subdiv);
+struct StrandCurveCache *BKE_strand_curve_cache_create_bm(struct BMesh *bm, int subdiv);
+void BKE_strand_curve_cache_free(struct StrandCurveCache *cache);
+int BKE_strand_curve_cache_calc(const struct StrandVertex *orig_verts, int orig_num_verts,
+                                struct StrandCurveCache *cache, float rootmat[4][4], int subdiv);
+int BKE_strand_curve_cache_calc_bm(struct BMVert *root, int orig_num_verts,
+                                   struct StrandCurveCache *cache, float rootmat[4][4], int subdiv);
+int BKE_strand_curve_cache_size(int orig_num_verts, int subdiv);
+int BKE_strand_curve_cache_totverts(int orig_totverts, int orig_totcurves, int subdiv);
 
 /* ------------------------------------------------------------------------- */
 
@@ -111,9 +78,12 @@ void BKE_strands_test_init(struct Strands *strands, struct DerivedMesh *scalp,
                            unsigned int seed);
 
 
-struct StrandFiber *BKE_strands_scatter(struct Strands *strands,
-                                       struct DerivedMesh *scalp, unsigned int amount,
-                                       unsigned int seed);
+void BKE_strands_scatter(struct Strands *strands,
+                         struct DerivedMesh *scalp, unsigned int amount,
+                         unsigned int seed);
+void BKE_strands_free_fibers(struct Strands *strands);
+
+void BKE_strands_free_drawdata(struct GPUDrawStrands *gpu_buffer);
 
 #if 0
 typedef struct StrandCurveParams {
diff --git a/source/blender/blenkernel/intern/editstrands.c b/source/blender/blenkernel/intern/editstrands.c
index 3b077f5..c259483 100644
--- a/source/blender/blenkernel/intern/editstrands.c
+++ b/source/blender/blenkernel/intern/editstrands.c
@@ -68,7 +68,7 @@ BMEditStrands *BKE_editstrands_create(BMesh *bm, DerivedMesh *root_dm, StrandFib
 	es->root_dm = CDDM_copy(root_dm);
 	if (fibers && num_fibers > 0) {
 		es->fibers = MEM_dupallocN(fibers);
-		es->num_fibers = num_fibers;
+		es->totfibers = num_fibers;
 	}
 	
 	return es;
@@ -83,11 +83,9 @@ BMEditStrands *BKE_editstrands_copy(BMEditStrands *es)
 	es_copy->root_dm = CDDM_copy(es->root_dm);
 	if (es->fibers) {
 		es_copy->fibers = MEM_dupallocN(es->fibers);
-		es_copy->num_fibers = es->num_fibers;
+		es_copy->totfibers = es->totfibers;
 	}
 	
-	es_copy->gpu_buffer = NULL;
-	
 	return es_copy;
 }
 
@@ -139,17 +137,6 @@ void BKE_editstrands_free(BMEditStrands *es)
 		es->root_dm->release(es->root_dm);
 	if (es->fibers)
 		MEM_freeN(es->fibers);
-	
-	if (es->gpu_buffer)
-		GPU_strands_buffer_free(es->gpu_buffer);
-}
-
-void BKE_editstrands_clear_drawdata(BMEditStrands *es)
-{
-	if (es->gpu_buffer) {
-		GPU_strands_buffer_free(es->gpu_buffer);
-		es->gpu_buffer = NULL;
-	}
 }
 
 /* === constraints === */
diff --git a/source/blender/blenkernel/intern/strands.c b/source/blender/blenkernel/intern/strands.c
index c745944..7682f77 100644
--- a/source/blender/blenkernel/intern/strands.c
+++ b/source/blender/blenkernel/intern/strands.c
@@ -44,6 +44,8 @@
 #include "GPU_buffers.h"
 #include "GPU_strands.h"
 
+#include "bmesh.h"
+
 Strands *BKE_strands_new(void)
 {
 	Strands *strands = MEM_callocN(sizeof(Strands), "strands");
@@ -60,10 +62,12 @@ Strands *BKE_strands_copy(Strands *strands)
 	if (strands->verts) {
 		nstrands->verts = MEM_dupallocN(strands->verts);
 	}
+	if (strands->fibers) {
+		nstrands->fibers = MEM_dupallocN(strands->fibers);
+	}
 	
 	/* lazy initialized */
 	nstrands->gpu_shader = NULL;
-	nstrands->data_final = NULL;
 	
 	return nstrands;
 }
@@ -73,13 +77,12 @@ void BKE_strands_free(Strands *strands)
 	if (strands->gpu_shader)
 		GPU_strand_shader_free(strands->gpu_shader);
 	
-	if (strands->data_final)
-		BKE_strand_data_free(strands->data_final);
-	
 	if (strands->curves)
 		MEM_freeN(strands->curves);
 	if (strands->verts)
 		MEM_freeN(strands->verts);
+	if (strands->fibers)
+		MEM_freeN(strands->fibers);
 	MEM_freeN(strands);
 }
 
@@ -141,23 +144,51 @@ bool BKE_strands_get_fiber_matrix(const StrandFiber *fiber, DerivedMesh *root_dm
 
 /* ------------------------------------------------------------------------- */
 
-int BKE_strand_data_numverts(int orig_num_verts, int subdiv)
+StrandCurveCache *BKE_strand_curve_cache_create(const Strands *strands, int subdiv)
 {
-	BLI_assert(orig_num_verts >= 2);
-	return (orig_num_verts - 1) * (1 << subdiv) + 1;
+	/* calculate max. necessary vertex array size */
+	int maxverts = 0;
+	for (int c = 0; c < strands->totcurves; ++c) {
+		int numverts = strands->curves[c].num_verts;
+		if (numverts > maxverts)
+			maxverts = numverts;
+	}
+	/* account for subdivision */
+	maxverts = BKE_strand_curve_cache_size(maxverts, subdiv);
+	
+	StrandCurveCache *cache = MEM_callocN(sizeof(StrandCurveCache), "StrandCurveCache");
+	cache->maxverts = maxverts;
+	cache->verts = MEM_mallocN(sizeof(float) * 3 * maxverts, "StrandCurveCache verts");
+	
+	return cache;
 }
 
-void BKE_strand_data_generate_verts(const StrandVertex *orig_verts, int orig_num_verts,
-                                    StrandVertexData *verts, float rootmat[4][4], int subdiv)
+StrandCurveCache *BKE_strand_curve_cache_create_bm(BMesh *bm, 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);
-		}
+	/* calculate max. necessary vertex array size */
+	int maxverts = BM_strand_verts_count_max(bm);
+	/* account for subdivision */
+	maxverts = BKE_strand_curve_cache_size(maxverts, subdiv);
+	
+	StrandCurveCache *cache = MEM_callocN(sizeof(StrandCurveCache), "StrandCurveCache");
+	cache->maxverts = maxverts;
+	cache->verts = MEM_mallocN(sizeof(float) * 3 * maxverts, "StrandCurveCache verts");
+	
+	return cache;
+}
+
+void BKE_strand_curve_cache_free(StrandCurveCache *cache)
+{
+	if (cache) {
+		if (cache->verts)
+			MEM_freeN(cache->verts);
+		MEM_freeN(cache);
 	}
+}
+
+static int curve_cache_subdivide(StrandCurveCache *cache, int orig_num_verts, int subdiv)
+{
+	float (*verts)[3] = cache->verts;
 	
 	/* subdivide */
 	for (int d = 0; d < subdiv; ++d) {
@@ -168,88 +199,68 @@ void BKE_strand_data_generate_verts(const StrandVertex *orig_verts, int orig_num
 		/* 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);
+			add_v3_v3v3(verts[index + hstep], verts[index], verts[index + step]);
+			mul_v3_fl(verts[index + hstep], 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);
+			add_v3_v3v3(verts[index], verts[index - hstep], verts[index + hstep]);
+			mul_v3_fl(verts[index], 0.5f);
 		}
 	}
+	
+	const int num_verts = (orig_num_verts - 1) * (1 << subdiv) + 1;
+	return num_verts;
 }
 
-static in

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list