[Bf-blender-cvs] [e96c24f] strand_gpu: Use the Strands modifier as a simple container for strand control curves.

Lukas Tönne noreply at git.blender.org
Tue Jul 5 09:56:51 CEST 2016


Commit: e96c24fea3cadeadc0fe0b32a3a543220c6ac01b
Author: Lukas Tönne
Date:   Wed Jun 29 10:40:20 2016 +0200
Branches: strand_gpu
https://developer.blender.org/rBe96c24fea3cadeadc0fe0b32a3a543220c6ac01b

Use the Strands modifier as a simple container for strand control curves.

These curves are NOT intended for final rendering! They are abstract
editable data (control strands) from which the "actual" visible strands
have to be generated in some way.

This is largely equivalent to the parent/child dichotomy in old particles,
but enforces the separation right from the start (control curves are never
rendered).

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

A	source/blender/blenkernel/BKE_strands.h
M	source/blender/blenkernel/CMakeLists.txt
A	source/blender/blenkernel/intern/strands.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/blenloader/intern/writefile.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesdna/DNA_strand_types.h
M	source/blender/modifiers/intern/MOD_strands.c

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

diff --git a/source/blender/blenkernel/BKE_strands.h b/source/blender/blenkernel/BKE_strands.h
new file mode 100644
index 0000000..9e329fb
--- /dev/null
+++ b/source/blender/blenkernel/BKE_strands.h
@@ -0,0 +1,60 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BKE_STRANDS_H__
+#define __BKE_STRANDS_H__
+
+/** \file blender/blenkernel/BKE_strands.h
+ *  \ingroup bke
+ */
+
+#include "BLI_utildefines.h"
+
+#include "DNA_strand_types.h"
+
+struct DerivedMesh;
+
+static const unsigned int STRAND_INDEX_NONE = 0xFFFFFFFF;
+
+struct Strands *BKE_strands_new(void);
+struct Strands *BKE_strands_copy(struct Strands *strands);
+void BKE_strands_free(struct Strands *strands);
+
+struct StrandInfo *BKE_strands_scatter(struct DerivedMesh *scalp, unsigned int amount,
+                                       const ControlStrand *controls, unsigned int num_controls,
+                                       unsigned int seed);
+
+typedef struct StrandCurveParams {
+	struct DerivedMesh *scalp;
+	unsigned int max_verts;
+} StrandCurveParams;
+
+struct StrandData *BKE_strand_data_interpolate(struct StrandInfo *strands, unsigned int num_strands,
+                                               const ControlStrand *controls, struct StrandCurveParams *params);
+void BKE_strand_data_free(struct StrandData *data);
+
+#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index b94eba7..036443c 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -171,6 +171,7 @@ set(SRC
 	intern/softbody.c
 	intern/sound.c
 	intern/speaker.c
+	intern/strands.c
 	intern/subsurf_ccg.c
 	intern/suggestions.c
 	intern/text.c
@@ -284,6 +285,7 @@ set(SRC
 	BKE_softbody.h
 	BKE_sound.h
 	BKE_speaker.h
+	BKE_strands.h
 	BKE_subsurf.h
 	BKE_suggestions.h
 	BKE_text.h
diff --git a/source/blender/blenkernel/intern/strands.c b/source/blender/blenkernel/intern/strands.c
new file mode 100644
index 0000000..b699825
--- /dev/null
+++ b/source/blender/blenkernel/intern/strands.c
@@ -0,0 +1,149 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/strands.c
+ *  \ingroup bke
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_math.h"
+
+#include "BKE_mesh_sample.h"
+#include "BKE_strands.h"
+
+Strands *BKE_strands_new(void)
+{
+	Strands *strands = MEM_callocN(sizeof(Strands), "strands");
+	return strands;
+}
+
+Strands *BKE_strands_copy(Strands *strands)
+{
+	Strands *nstrands = MEM_dupallocN(strands);
+	
+	if (strands->controls) {
+		nstrands->controls = MEM_dupallocN(strands->controls);
+	}
+	
+	return nstrands;
+}
+
+void BKE_strands_free(Strands *strands)
+{
+	MEM_freeN(strands);
+}
+
+StrandInfo *BKE_strands_scatter(struct DerivedMesh *scalp, unsigned int amount,
+                                const ControlStrand *controls, unsigned int num_controls,
+                                unsigned int seed)
+{
+	MeshSampleGenerator *gen = BKE_mesh_sample_gen_surface_random(scalp, seed);
+	unsigned int i;
+	
+	StrandInfo *strands = MEM_mallocN(sizeof(StrandInfo) * amount, "strands");
+	StrandInfo *s;
+	
+	UNUSED_VARS(controls, num_controls);
+	for (i = 0, s = strands; i < amount; ++i, ++s) {
+		if (BKE_mesh_sample_generate(gen, &s->root)) {
+			int k;
+			/* TODO find weights to "nearest" control strands */
+			for (k = 0; k < 4; ++k) {
+				s->control_index[k] = STRAND_INDEX_NONE;
+				s->control_weights[k] = 0.0f;
+			}
+		}
+		else {
+			/* clear remaining samples */
+			memset(s, 0, sizeof(StrandInfo) * amount - i);
+			break;
+		}
+	}
+	
+	BKE_mesh_sample_free_generator(gen);
+	
+	return strands;
+}
+
+StrandData *BKE_strand_data_interpolate(StrandInfo *strands, unsigned int num_strands,
+                                        const ControlStrand *controls, struct StrandCurveParams *params)
+{
+	StrandData *data = MEM_callocN(sizeof(StrandData), "strand interpolation data");
+	StrandInfo *s;
+	StrandCurve *c;
+	StrandVertex *v;
+	unsigned int verts_begin;
+	unsigned int i;
+	
+	data->totcurves = num_strands;
+	data->totverts = num_strands * params->max_verts;
+	data->curves = MEM_mallocN(sizeof(StrandCurve) * data->totcurves, "strand curves");
+	data->verts = MEM_mallocN(sizeof(StrandVertex) * data->totverts, "strand vertices");
+	
+	UNUSED_VARS(controls);
+	verts_begin = 0;
+	v = data->verts;
+	for (i = 0, s = strands, c = data->curves; i < num_strands; ++i) {
+		unsigned int k;
+		
+		c->num_verts = params->max_verts;
+		c->verts_begin = verts_begin;
+		
+		if (params->scalp) {
+			BKE_mesh_sample_eval(params->scalp, &s->root, c->rootmat[3], c->rootmat[2], c->rootmat[0]);
+			cross_v3_v3v3(c->rootmat[1], c->rootmat[2], c->rootmat[0]);
+		}
+		else {
+			unit_m4(c->rootmat);
+		}
+		
+		for (k = 0; k < c->num_verts; ++k, ++v) {
+			v->co[0] = 0.0f;
+			v->co[1] = 0.0f;
+			if (c->num_verts > 1)
+				v->co[2] = k / (c->num_verts - 1);
+		}
+		
+		verts_begin += c->num_verts;
+	}
+	
+	return data;
+}
+
+void BKE_strand_data_free(StrandData *data)
+{
+	if (data) {
+		if (data->curves)
+			MEM_freeN(data->curves);
+		if (data->verts)
+			MEM_freeN(data->verts);
+		MEM_freeN(data);
+	}
+}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 323f0a9..7fc0d1c 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -96,6 +96,7 @@
 #include "DNA_speaker_types.h"
 #include "DNA_sound_types.h"
 #include "DNA_space_types.h"
+#include "DNA_strand_types.h"
 #include "DNA_vfont_types.h"
 #include "DNA_world_types.h"
 #include "DNA_movieclip_types.h"
@@ -4300,6 +4301,16 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles)
 	return;
 }
 
+/* ************ READ STRANDS ***************** */
+
+static void direct_link_strands(FileData *fd, Strands *strands)
+{
+	if (strands == NULL)
+		return;
+	
+	strands->controls = newdataadr(fd, strands->controls);
+}
+
 /* ************ READ MESH ***************** */
 
 static void lib_link_mtface(FileData *fd, Mesh *me, MTFace *mtface, int totface)
@@ -5259,6 +5270,14 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
 			csmd->delta_cache = NULL;
 			csmd->delta_cache_num = 0;
 		}
+		else if (md->type == eModifierType_Strands) {
+			StrandsModifierData *smd = (StrandsModifierData*)md;
+
+			if (smd->strands) {
+				smd->strands = newdataadr(fd, smd->strands);
+				direct_link_strands(fd, smd->strands);
+			}
+		}
 	}
 }
 
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 7a84eb6..5be45c5 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -140,6 +140,7 @@
 #include "DNA_screen_types.h"
 #include "DNA_speaker_types.h"
 #include "DNA_sound_types.h"
+#include "DNA_strand_types.h"
 #include "DNA_text_types.h"
 #include "DNA_view3d_types.h"
 #include "DNA_vfont_types.h"
@@ -1252,6 +1253,18 @@ static void write_particlesystems(WriteData *wd, ListBase *particles)
 	}
 }
 
+static void write_strands(WriteData *wd, Strands *strands)
+{
+	if (strands == NULL)
+		return;
+	
+	writestruct(wd, DATA, "Strands", 1, strands);
+	
+	if (strands->controls) {
+		writestruct(wd, DATA, "ControlStrand", strands->num_controls, strands->controls);
+	}
+}
+
 static void write_properties(WriteData *wd, ListBase *lb)
 {
 	bProperty *prop;
@@ -1668,6 +1681,13 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
 				writedata(wd, DATA, sizeof(float[3]) * csmd->bind_coords_num, csmd->bind_coords);
 			}
 		}
+		else if (md->type == eModifierType_Strands) {
+			StrandsModifierData *smd = (StrandsModifierData *)md;
+
+			if (smd->strands) {
+				write_strands(wd, smd->strands);
+			}
+		}
 	}
 }
 
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 28ee2c8..2e4d54a 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1547,6 +1547,8 @@ enum {
 /* Strand modifier */
 typedef struct StrandsModifierData {
 	ModifierData modifier;
+	
+	struct Strands *strands;
 } StrandsModifierData;
 
 #endif  /* __DNA_MODIFIER_TYPES_H__ */
diff --git a/source/blender/makesdna/DNA_strand_types.h b/sour

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list