[Bf-blender-cvs] [64e3661] gooseberry: Store particle index and randomized value from particle instance modifiers, for use in shaders.

Lukas Tönne noreply at git.blender.org
Mon Feb 16 14:33:18 CET 2015


Commit: 64e3661434f11b4201c08cac1e99f08853551c86
Author: Lukas Tönne
Date:   Mon Feb 16 14:30:07 2015 +0100
Branches: gooseberry
https://developer.blender.org/rB64e3661434f11b4201c08cac1e99f08853551c86

Store particle index and randomized value from particle instance
modifiers, for use in shaders.

The particle instance modifier can now store 2 custom data layers:
- Index: the integer index of the particle
- Value: a randomized floating point number for shader variation

These layers have user-defined names, so multiple particle instance
modifiers can be used without overwriting customdata layers. In Cycles
the data can be accessed using an Attribute node with the same names.

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

M	intern/cycles/blender/blender_mesh.cpp
M	release/scripts/startup/bl_ui/properties_data_modifier.py
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_particleinstance.c

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

diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index c5e2fa2..7f3752d 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -419,6 +419,52 @@ static void attr_create_pointiness(Scene *scene,
 	}
 }
 
+/* Create vertex custom attributes. */
+static void attr_create_vertex_properties(Scene *scene,
+                                          Mesh *mesh,
+                                          BL::Mesh b_mesh)
+{
+	{
+		BL::Mesh::vertex_layers_float_iterator l;
+		for(b_mesh.vertex_layers_float.begin(l); l != b_mesh.vertex_layers_float.end(); ++l) {
+			if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
+				continue;
+			
+			Attribute *attr = mesh->attributes.add(
+			            ustring(l->name().c_str()), TypeDesc::TypeFloat, ATTR_ELEMENT_VERTEX);
+			
+			BL::MeshVertexFloatPropertyLayer::data_iterator d;
+			float *data = attr->data_float();
+			size_t i = 0;
+			
+			for(l->data.begin(d); d != l->data.end(); ++d, ++i) {
+				*data = d->value();
+				data += 1;
+			}
+		}
+	}
+
+	{
+		BL::Mesh::vertex_layers_int_iterator l;
+		for(b_mesh.vertex_layers_int.begin(l); l != b_mesh.vertex_layers_int.end(); ++l) {
+			if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
+				continue;
+			
+			Attribute *attr = mesh->attributes.add(
+			            ustring(l->name().c_str()), TypeDesc::TypeFloat, ATTR_ELEMENT_VERTEX);
+			
+			BL::MeshVertexIntPropertyLayer::data_iterator d;
+			float *data = attr->data_float();
+			size_t i = 0;
+			
+			for(l->data.begin(d); d != l->data.end(); ++d, ++i) {
+				*data = (float)d->value();
+				data += 1;
+			}
+		}
+	}
+}
+
 /* Create Mesh */
 
 static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<uint>& used_shaders)
@@ -523,6 +569,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
 	attr_create_vertex_color(scene, mesh, b_mesh, nverts);
 	attr_create_uv_map(scene, mesh, b_mesh, nverts);
 	attr_create_pointiness(scene, mesh, b_mesh);
+	attr_create_vertex_properties(scene, mesh, b_mesh);
 
 	/* for volume objects, create a matrix to transform from object space to
 	 * mesh texture space. this does not work with deformations but that can
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 2a27610..d524d26 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -682,6 +682,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         col.prop(md, "position", slider=True)
         col.prop(md, "random_position", text="Random", slider=True)
 
+        col = layout.column(align=True)
+        col.prop(md, "index_layer_name", text="Index Layer")
+        col.prop(md, "value_layer_name", text="Value Layer")
+
     def PARTICLE_SYSTEM(self, layout, ob, md):
         layout.label(text="Settings can be found inside the Particle context")
 
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index e603f3e..414d1d7 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -712,14 +712,14 @@ typedef enum {
 } ParticleSystemModifierFlag;
 
 typedef enum {
-	eParticleInstanceFlag_Parents   = (1 << 0),
-	eParticleInstanceFlag_Children  = (1 << 1),
-	eParticleInstanceFlag_Path      = (1 << 2),
-	eParticleInstanceFlag_Unborn    = (1 << 3),
-	eParticleInstanceFlag_Alive     = (1 << 4),
-	eParticleInstanceFlag_Dead      = (1 << 5),
-	eParticleInstanceFlag_KeepShape = (1 << 6),
-	eParticleInstanceFlag_UseSize   = (1 << 7),
+	eParticleInstanceFlag_Parents       = (1 << 0),
+	eParticleInstanceFlag_Children      = (1 << 1),
+	eParticleInstanceFlag_Path          = (1 << 2),
+	eParticleInstanceFlag_Unborn        = (1 << 3),
+	eParticleInstanceFlag_Alive         = (1 << 4),
+	eParticleInstanceFlag_Dead          = (1 << 5),
+	eParticleInstanceFlag_KeepShape     = (1 << 6),
+	eParticleInstanceFlag_UseSize       = (1 << 7),
 } ParticleInstanceModifierFlag;
 
 typedef enum {
@@ -734,6 +734,8 @@ typedef struct ParticleInstanceModifierData {
 	short psys, flag, axis, space;
 	float position, random_position;
 	float particle_amount, particle_offset;
+	char index_layer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
+	char value_layer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
 } ParticleInstanceModifierData;
 
 typedef enum {
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 3a72119..8c4c33f 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -2448,6 +2448,16 @@ static void rna_def_modifier_particleinstance(BlenderRNA *brna)
 	RNA_def_property_ui_text(prop, "Particle Offset", "Relative offset of particles to use for instancing, to avoid overlap of multiple instances");
 	RNA_def_property_float_default(prop, 0.0f);
 	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+	prop = RNA_def_property(srna, "index_layer_name", PROP_STRING, PROP_NONE);
+	RNA_def_property_string_sdna(prop, NULL, "index_layer_name");
+	RNA_def_property_ui_text(prop, "Index Layer Name", "Custom data layer name for the index");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+	prop = RNA_def_property(srna, "value_layer_name", PROP_STRING, PROP_NONE);
+	RNA_def_property_string_sdna(prop, NULL, "value_layer_name");
+	RNA_def_property_ui_text(prop, "Value Layer Name", "Custom data layer name for the randomized value");
+	RNA_def_property_update(prop, 0, "rna_Modifier_update");
 }
 
 static void rna_def_modifier_explode(BlenderRNA *brna)
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index f7092c7..853790e 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -40,6 +40,7 @@
 #include "BLI_math.h"
 #include "BLI_listbase.h"
 #include "BLI_rand.h"
+#include "BLI_string.h"
 #include "BLI_utildefines.h"
 
 #include "BKE_cdderivedmesh.h"
@@ -65,6 +66,9 @@ static void initData(ModifierData *md)
 	pimd->space = eParticleInstanceSpace_Local;
 	pimd->particle_amount = 1.0f;
 	pimd->particle_offset = 0.0f;
+	
+	BLI_strncpy(pimd->index_layer_name, "particle_index", sizeof(pimd->index_layer_name));
+	BLI_strncpy(pimd->value_layer_name, "particle_value", sizeof(pimd->value_layer_name));
 }
 static void copyData(ModifierData *md, ModifierData *target)
 {
@@ -208,6 +212,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
 	float max_co = 0.0, min_co = 0.0, temp_co[3];
 	float *size = NULL;
 	float spacemat[4][4];
+	int *cd_index = NULL;
+	float *cd_value = NULL;
 
 	trackneg = ((ob->trackflag > 2) ? 1 : 0);
 
@@ -313,9 +319,18 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
 	mloop = result->getLoopArray(result);
 	orig_mloop = dm->getLoopArray(dm);
 
+	/* create customdata layer for particle index storage */
+	if (pimd->index_layer_name[0] != '\0')
+		cd_index = CustomData_add_layer_named(&result->vertData, CD_PROP_INT, CD_CALLOC,
+		                                         NULL, maxvert, pimd->index_layer_name);
+	if (pimd->value_layer_name[0] != '\0')
+		cd_value = CustomData_add_layer_named(&result->vertData, CD_PROP_FLT, CD_CALLOC,
+		                                       NULL, maxvert, pimd->value_layer_name);
+
 	for (p = 0, p_skip = 0; p < totpart; p++) {
 		float prev_dir[3];
 		float frame[4]; /* frame orientation quaternion */
+		float p_random = psys_frand(psys, 77091 + 283*p);
 		
 		/* skip particle? */
 		if (particle_skip(pimd, psys, p))
@@ -325,12 +340,18 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
 		for (k = 0; k < totvert; k++) {
 			ParticleKey state;
 			MVert *inMV;
-			MVert *mv = mvert + p_skip * totvert + k;
+			int vindex = p_skip * totvert + k;
+			MVert *mv = mvert + vindex;
 
 			inMV = orig_mvert + k;
 			DM_copy_vert_data(dm, result, k, p_skip * totvert + k, 1);
 			*mv = *inMV;
 
+			if (cd_index)
+				cd_index[vindex] = p;
+			if (cd_value)
+				cd_value[vindex] = p_random;
+
 			/*change orientation based on object trackflag*/
 			copy_v3_v3(temp_co, mv->co);
 			mv->co[axis] = temp_co[track];




More information about the Bf-blender-cvs mailing list