[Bf-blender-cvs] [aee5f39] alembic: Child strands structure for storing renderable child hairs efficiently.

Lukas Tönne noreply at git.blender.org
Wed Apr 8 19:22:16 CEST 2015


Commit: aee5f39e106c98c4aa1bb4ff5b98d354c27d3e41
Author: Lukas Tönne
Date:   Wed Apr 8 13:43:01 2015 +0200
Branches: alembic
https://developer.blender.org/rBaee5f39e106c98c4aa1bb4ff5b98d354c27d3e41

Child strands structure for storing renderable child hairs efficiently.

This is a separate struct to avoid storing unnecessary data (this means
a bit of code duplication for iterators). The child strands can be used
as the actual render data, while the parent strands usually would be
used only for simulation/deformation purposes.

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

M	source/blender/blenkernel/BKE_strands.h
M	source/blender/blenkernel/intern/strands.c

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

diff --git a/source/blender/blenkernel/BKE_strands.h b/source/blender/blenkernel/BKE_strands.h
index 5ba01e0..c557aaf 100644
--- a/source/blender/blenkernel/BKE_strands.h
+++ b/source/blender/blenkernel/BKE_strands.h
@@ -64,7 +64,33 @@ void BKE_strands_ensure_normals(struct Strands *strands);
 
 void BKE_strands_get_minmax(struct Strands *strands, float min[3], float max[3], bool use_motion_state);
 
+typedef struct StrandsChildCurve {
+	int numverts;
+} StrandsChildCurve;
+
+typedef struct StrandsChildVertex {
+	float co[3];
+	float time;
+	
+	/* utility data */
+	float nor[3]; /* normals (edge directions) */
+} StrandsChildVertex;
+
+typedef struct StrandsChildren {
+	StrandsChildCurve *curves;
+	StrandsChildVertex *verts;
+	int totcurves, totverts;
+} StrandsChildren;
+
+struct StrandsChildren *BKE_strands_children_new(int strands, int verts);
+void BKE_strands_children_free(struct StrandsChildren *strands);
+
+void BKE_strands_children_ensure_normals(struct StrandsChildren *strands);
+
+void BKE_strands_children_get_minmax(struct StrandsChildren *strands, float min[3], float max[3]);
+
 /* ------------------------------------------------------------------------- */
+/* Strand Curves Iterator */
 
 typedef struct StrandIterator {
 	int index, tot;
@@ -108,6 +134,8 @@ BLI_INLINE size_t BKE_strand_iter_vertex_offset(Strands *strands, StrandIterator
 	return iter->verts - strands->verts;
 }
 
+/* ------------------------------------------------------------------------- */
+/* Strand Vertices Iterator */
 
 typedef struct StrandVertexIterator {
 	int index, tot;
@@ -141,6 +169,8 @@ BLI_INLINE size_t BKE_strand_vertex_iter_vertex_offset(Strands *strands, StrandV
 	return iter->vertex - strands->verts;
 }
 
+/* ------------------------------------------------------------------------- */
+/* Strand Edges Iterator */
 
 typedef struct StrandEdgeIterator {
 	int index, tot;
@@ -184,6 +214,8 @@ BLI_INLINE size_t BKE_strand_edge_iter_vertex1_offset(Strands *strands, StrandEd
 	return iter->vertex1 - strands->verts;
 }
 
+/* ------------------------------------------------------------------------- */
+/* Strand Bends Iterator */
 
 typedef struct StrandBendIterator {
 	int index, tot;
@@ -239,4 +271,114 @@ BLI_INLINE size_t BKE_strand_bend_iter_vertex2_offset(Strands *strands, StrandBe
 void BKE_strand_bend_iter_transform_rest(StrandBendIterator *iter, float mat[3][3]);
 void BKE_strand_bend_iter_transform_state(StrandBendIterator *iter, float mat[3][3]);
 
+/* ------------------------------------------------------------------------- */
+/* Strand Child Curves Iterator */
+
+typedef struct StrandChildIterator {
+	int index, tot;
+	StrandsChildCurve *curve;
+	StrandsChildVertex *verts;
+} StrandChildIterator;
+
+BLI_INLINE void BKE_strand_child_iter_init(StrandChildIterator *iter, StrandsChildren *strands)
+{
+	iter->tot = strands->totcurves;
+	iter->index = 0;
+	iter->curve = strands->curves;
+	iter->verts = strands->verts;
+}
+
+BLI_INLINE bool BKE_strand_child_iter_valid(StrandChildIterator *iter)
+{
+	return iter->index < iter->tot;
+}
+
+BLI_INLINE void BKE_strand_child_iter_next(StrandChildIterator *iter)
+{
+	const int numverts = iter->curve->numverts;
+	
+	++iter->index;
+	++iter->curve;
+	iter->verts += numverts;
+}
+
+BLI_INLINE size_t BKE_strand_child_iter_curve_offset(StrandsChildren *strands, StrandChildIterator *iter)
+{
+	return iter->curve - strands->curves;
+}
+
+BLI_INLINE size_t BKE_strand_child_iter_vertex_offset(StrandsChildren *strands, StrandChildIterator *iter)
+{
+	return iter->verts - strands->verts;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Strand Child Vertices Iterator */
+
+typedef struct StrandChildVertexIterator {
+	int index, tot;
+	StrandsChildVertex *vertex;
+} StrandChildVertexIterator;
+
+BLI_INLINE void BKE_strand_child_vertex_iter_init(StrandChildVertexIterator *iter, StrandChildIterator *strand_iter)
+{
+	iter->tot = strand_iter->curve->numverts;
+	iter->index = 0;
+	iter->vertex = strand_iter->verts;
+}
+
+BLI_INLINE bool BKE_strand_child_vertex_iter_valid(StrandChildVertexIterator *iter)
+{
+	return iter->index < iter->tot;
+}
+
+BLI_INLINE void BKE_strand_child_vertex_iter_next(StrandChildVertexIterator *iter)
+{
+	++iter->vertex;
+	++iter->index;
+}
+
+BLI_INLINE size_t BKE_strand_child_vertex_iter_vertex_offset(StrandsChildren *strands, StrandChildVertexIterator *iter)
+{
+	return iter->vertex - strands->verts;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Strand Child Edges Iterator */
+
+typedef struct StrandChildEdgeIterator {
+	int index, tot;
+	StrandsChildVertex *vertex0, *vertex1;
+} StrandChildEdgeIterator;
+
+BLI_INLINE void BKE_strand_child_edge_iter_init(StrandChildEdgeIterator *iter, StrandChildIterator *strand_iter)
+{
+	iter->tot = strand_iter->curve->numverts - 1;
+	iter->index = 0;
+	iter->vertex0 = strand_iter->verts;
+	iter->vertex1 = strand_iter->verts + 1;
+}
+
+BLI_INLINE bool BKE_strand_child_edge_iter_valid(StrandChildEdgeIterator *iter)
+{
+	return iter->index < iter->tot;
+}
+
+BLI_INLINE void BKE_strand_child_edge_iter_next(StrandChildEdgeIterator *iter)
+{
+	++iter->vertex0;
+	++iter->vertex1;
+	++iter->index;
+}
+
+BLI_INLINE size_t BKE_strand_child_edge_iter_vertex0_offset(StrandsChildren *strands, StrandChildEdgeIterator *iter)
+{
+	return iter->vertex0 - strands->verts;
+}
+
+BLI_INLINE size_t BKE_strand_child_edge_iter_vertex1_offset(StrandsChildren *strands, StrandChildEdgeIterator *iter)
+{
+	return iter->vertex1 - strands->verts;
+}
+
 #endif  /* __BKE_STRANDS_H__ */
diff --git a/source/blender/blenkernel/intern/strands.c b/source/blender/blenkernel/intern/strands.c
index 54dd5b9..709038f 100644
--- a/source/blender/blenkernel/intern/strands.c
+++ b/source/blender/blenkernel/intern/strands.c
@@ -25,18 +25,18 @@
 
 Strands *BKE_strands_new(int curves, int verts)
 {
-	Strands *s = MEM_mallocN(sizeof(Strands), "strands");
+	Strands *strands = MEM_mallocN(sizeof(Strands), "strands");
 	
-	s->totcurves = curves;
-	s->curves = MEM_mallocN(sizeof(StrandsCurve) * curves, "strand curves");
+	strands->totcurves = curves;
+	strands->curves = MEM_mallocN(sizeof(StrandsCurve) * curves, "strand curves");
 	
-	s->totverts = verts;
-	s->verts = MEM_mallocN(sizeof(StrandsVertex) * verts, "strand vertices");
+	strands->totverts = verts;
+	strands->verts = MEM_mallocN(sizeof(StrandsVertex) * verts, "strand vertices");
 	
 	/* must be added explicitly */
-	s->state = NULL;
+	strands->state = NULL;
 	
-	return s;
+	return strands;
 }
 
 void BKE_strands_free(Strands *strands)
@@ -106,20 +106,23 @@ static void calc_normals(Strands *strands, bool use_motion_state)
 {
 	StrandIterator it_strand;
 	for (BKE_strand_iter_init(&it_strand, strands); BKE_strand_iter_valid(&it_strand); BKE_strand_iter_next(&it_strand)) {
-		StrandVertexIterator it_vert;
-		BKE_strand_vertex_iter_init(&it_vert, &it_strand);
-		
-		if (BKE_strand_vertex_iter_valid(&it_vert)) {
-			const float *co_prev = use_motion_state ? it_vert.state->co : it_vert.vertex->co;
-			
-			BKE_strand_vertex_iter_next(&it_vert);
-			
-			for (; BKE_strand_vertex_iter_valid(&it_vert); BKE_strand_vertex_iter_next(&it_vert)) {
-				const float *co = use_motion_state ? it_vert.state->co : it_vert.vertex->co;
-				float *nor = use_motion_state ? it_vert.state->nor : it_vert.vertex->nor;
-				
-				sub_v3_v3v3(nor, co, co_prev);
-				normalize_v3(nor);
+		StrandEdgeIterator it_edge;
+		if (use_motion_state) {
+			for (BKE_strand_edge_iter_init(&it_edge, &it_strand); BKE_strand_edge_iter_valid(&it_edge); BKE_strand_edge_iter_next(&it_edge)) {
+				sub_v3_v3v3(it_edge.state0->nor, it_edge.state1->co, it_edge.state0->co);
+				normalize_v3(it_edge.state0->nor);
+			}
+			if (it_strand.tot > 0) {
+				copy_v3_v3(it_edge.state1->nor, it_edge.state0->nor);
+			}
+		}
+		else {
+			for (BKE_strand_edge_iter_init(&it_edge, &it_strand); BKE_strand_edge_iter_valid(&it_edge); BKE_strand_edge_iter_next(&it_edge)) {
+				sub_v3_v3v3(it_edge.vertex0->nor, it_edge.vertex1->co, it_edge.vertex0->co);
+				normalize_v3(it_edge.vertex0->nor);
+			}
+			if (it_strand.tot > 0) {
+				copy_v3_v3(it_edge.vertex1->nor, it_edge.vertex0->nor);
 			}
 		}
 	}
@@ -154,6 +157,62 @@ void BKE_strands_get_minmax(Strands *strands, float min[3], float max[3], bool u
 
 /* ------------------------------------------------------------------------- */
 
+StrandsChildren *BKE_strands_children_new(int curves, int verts)
+{
+	StrandsChildren *strands = MEM_mallocN(sizeof(StrandsChildren), "strands children");
+	
+	strands->totcurves = curves;
+	strands->curves = MEM_mallocN(sizeof(StrandsChildCurve) * curves, "strand children curves");
+	
+	strands->totverts = verts;
+	strands->verts = MEM_mallocN(sizeof(StrandsChildVertex) * verts, "strand children vertices");
+	
+	return strands;
+}
+
+void BKE_strands_children_free(StrandsChildren *strands)
+{
+	if (strands) {
+		if (strands->curves)
+			MEM_freeN(strands->curves);
+		if (strands->verts)
+			MEM_freeN(strands->verts);
+		MEM_freeN(strands);
+	}
+}
+
+static void calc_child_normals(StrandsChildren *strands)
+{
+	StrandChildIterator it_strand;
+	for (BKE_strand_child_iter_init(&it_strand, strands); BKE_strand_child_iter_valid(&it_strand); BKE_strand_child_iter_next(&it_strand)) {
+		StrandChildEdgeIterator it_edge;
+		for (BKE_strand_child_edge_iter_init(&it_edge, &it_strand); BKE_strand_child_edge_iter_valid(&it_edge); BKE_strand_child_edge_iter_next(&it_edge)) {
+			sub_v3_v3v3(it_edge.vertex0->nor, it_edge.vertex1->co, it_edge.vertex0->co);
+			normalize_v3(it_edge.vertex0->nor);
+		}
+		if (it_strand.tot > 0) {
+			copy_v3_v3(it_edge.vertex1->nor, it_edge.vertex0->nor);
+		}
+	}
+}
+
+void BKE_strands_children_ensure_normals(StrandsChildren *strands)
+{
+	calc_child_normals(strands);
+}
+
+void BKE_strands_children_get_minmax(StrandsChildren *strands, float min[3], float max[3])
+{
+	int numverts = strands->totverts;
+	int i;
+	
+	for (i = 0; i < numverts; ++i) {
+		minmax_v3v3_v3(min, max, strands->verts[i].co);
+	}
+}
+
+/* ------------------------------------------------------------------------- */
+
 void BKE_strand_bend_iter_transform_rest(S

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list