[Bf-blender-cvs] [288010c] hair_system: Expose the hair render data via an emitter in the RNA for cycles.

Lukas Tönne noreply at git.blender.org
Wed Aug 13 15:43:29 CEST 2014


Commit: 288010c1c2dacde87756f34cb48af8f239012957
Author: Lukas Tönne
Date:   Wed Aug 13 13:11:17 2014 +0200
Branches: hair_system
https://developer.blender.org/rB288010c1c2dacde87756f34cb48af8f239012957

Expose the hair render data via an emitter in the RNA for cycles.

The way this has to be constructed is quite ugly atm, due to limited
support for transient data such as iterators in the RNA. The alternative
would be to cache the hair data as a whole, which means allocating and
copying lots of memory. Eventually it would be nice to support this sort
of think in the RNA API ...

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

M	source/blender/blenkernel/BKE_hair.h
M	source/blender/blenkernel/intern/hair.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/makesdna/DNA_hair_types.h
M	source/blender/makesrna/intern/rna_hair.c

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

diff --git a/source/blender/blenkernel/BKE_hair.h b/source/blender/blenkernel/BKE_hair.h
index c1cbbd3..6bf07f6 100644
--- a/source/blender/blenkernel/BKE_hair.h
+++ b/source/blender/blenkernel/BKE_hair.h
@@ -89,6 +89,7 @@ typedef struct HairRenderIterator {
 
 void BKE_hair_render_iter_init(struct HairRenderIterator *iter, struct HairSystem *hsys);
 void BKE_hair_render_iter_end(struct HairRenderIterator *iter);
+bool BKE_hair_render_iter_initialized(struct HairRenderIterator *iter);
 void BKE_hair_render_iter_init_hair(struct HairRenderIterator *iter);
 bool BKE_hair_render_iter_valid_hair(struct HairRenderIterator *iter);
 bool BKE_hair_render_iter_valid_step(struct HairRenderIterator *iter);
diff --git a/source/blender/blenkernel/intern/hair.c b/source/blender/blenkernel/intern/hair.c
index 4e14d8b..da9dbb6 100644
--- a/source/blender/blenkernel/intern/hair.c
+++ b/source/blender/blenkernel/intern/hair.c
@@ -70,6 +70,9 @@ void BKE_hairsys_free(HairSystem *hsys)
 		MEM_freeN(hsys->curves);
 	}
 	
+	if (hsys->render_iter)
+		MEM_freeN(hsys->render_iter);
+	
 	MEM_freeN(hsys);
 }
 
@@ -82,6 +85,8 @@ HairSystem *BKE_hairsys_copy(HairSystem *hsys)
 	for (i = 0; i < totcurves; ++i)
 		thsys->curves[i].points = MEM_dupallocN(hsys->curves[i].points);
 	
+	thsys->render_iter = NULL;
+	
 	return thsys;
 }
 
@@ -355,11 +360,22 @@ void BKE_hair_render_iter_init_hair(HairRenderIterator *iter)
 
 void BKE_hair_render_iter_end(HairRenderIterator *iter)
 {
-	if (iter->hair_cache)
+	if (iter->hair_cache) {
 		MEM_freeN(iter->hair_cache);
+		iter->hair_cache = NULL;
+	}
 	
-	if (iter->child_data)
+	if (iter->child_data) {
 		MEM_freeN(iter->child_data);
+		iter->child_data = NULL;
+	}
+	
+	iter->hair = NULL; /* indicates uninitialized iterator */
+}
+
+bool BKE_hair_render_iter_initialized(HairRenderIterator *iter)
+{
+	return iter->hair != NULL || iter->hair_cache || iter->child_data;
 }
 
 bool BKE_hair_render_iter_valid_hair(HairRenderIterator *iter)
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 6365770..ea15809 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4593,6 +4593,8 @@ static void direct_link_hair_system(FileData *fd, HairSystem *hsys)
 	for (hair = hsys->curves, i = 0; i < hsys->totcurves; ++hair, ++i) {
 		hair->points = newdataadr(fd, hair->points);
 	}
+	
+	hsys->render_iter = NULL;
 }
 
 static void direct_link_modifiers(FileData *fd, ListBase *lb)
diff --git a/source/blender/makesdna/DNA_hair_types.h b/source/blender/makesdna/DNA_hair_types.h
index 90270f6..b33ba0e 100644
--- a/source/blender/makesdna/DNA_hair_types.h
+++ b/source/blender/makesdna/DNA_hair_types.h
@@ -96,6 +96,8 @@ typedef struct HairSystem {
 	
 	HairParams params;
 	HairDisplaySettings display;
+	
+	struct HairRenderIterator *render_iter; /* runtime RNA utility pointer */
 } HairSystem;
 
 typedef struct HairDebugData {
diff --git a/source/blender/makesrna/intern/rna_hair.c b/source/blender/makesrna/intern/rna_hair.c
index 35636a1..3a5d85e 100644
--- a/source/blender/makesrna/intern/rna_hair.c
+++ b/source/blender/makesrna/intern/rna_hair.c
@@ -43,8 +43,14 @@
 
 #ifdef RNA_RUNTIME
 
+#include "BKE_hair.h"
+
+#include "RNA_access.h"
+
 #include "WM_api.h"
 
+#include "MEM_guardedalloc.h"
+
 #if 0 /* unused */
 static void rna_HairSystem_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
 {
@@ -62,6 +68,76 @@ static void rna_HairParams_render_update(Main *UNUSED(bmain), Scene *UNUSED(scen
 	WM_main_add_notifier(NC_OBJECT|ND_DRAW, ptr->id.data);
 }
 
+static PointerRNA rna_HairSystem_render_get(PointerRNA *ptr)
+{
+	HairSystem *hsys = ptr->data;
+	PointerRNA r_ptr;
+	
+	if (!hsys->render_iter) {
+		hsys->render_iter = MEM_callocN(sizeof(HairRenderIterator), "hair render iterator RNA instance");
+		/* store the hsys here already, so callers
+		 * don't have to pass it explicitly again in the init function */
+		hsys->render_iter->hsys = hsys;
+	}
+	
+	RNA_pointer_create(ptr->id.data, &RNA_HairRenderIterator, hsys->render_iter, &r_ptr);
+	return r_ptr;
+}
+
+static void rna_HairRenderIterator_init(HairRenderIterator *iter)
+{
+	/* make sure the iterator is uninitialized first */
+	if (BKE_hair_render_iter_initialized(iter))
+		BKE_hair_render_iter_end(iter);
+	
+	BKE_hair_render_iter_init(iter, iter->hsys);
+}
+
+static void rna_HairRenderIterator_end(HairRenderIterator *iter)
+{
+	BKE_hair_render_iter_end(iter);
+}
+
+static int rna_HairRenderIterator_valid(HairRenderIterator *iter)
+{
+	return BKE_hair_render_iter_valid_hair(iter);
+}
+
+static PointerRNA rna_HairRenderIterator_step_init(ID *id, HairRenderIterator *iter)
+{
+	PointerRNA r_ptr;
+	
+	if (!BKE_hair_render_iter_initialized(iter)) {
+		RNA_pointer_create(id, &RNA_HairRenderStepIterator, NULL, &r_ptr);
+		return r_ptr;
+	}
+	
+	BKE_hair_render_iter_init_hair(iter);
+	
+	RNA_pointer_create(id, &RNA_HairRenderStepIterator, iter, &r_ptr);
+	return r_ptr;
+}
+
+//static void rna_HairRenderStepIterator_init(HairRenderIterator *iter)
+//{
+//	BKE_hair_render_iter_init_hair(iter);
+//}
+
+static int rna_HairRenderStepIterator_valid(HairRenderIterator *iter)
+{
+	return BKE_hair_render_iter_valid_step(iter);
+}
+
+static void rna_HairRenderStepIterator_next(HairRenderIterator *iter)
+{
+	BKE_hair_render_iter_next(iter);
+}
+
+static void rna_HairRenderStepIterator_eval(HairRenderIterator *iter, float co[3], float *radius)
+{
+	BKE_hair_render_iter_get(iter, co, radius);
+}
+
 #else
 
 static void rna_def_hair_params(BlenderRNA *brna)
@@ -201,12 +277,79 @@ static void rna_def_hair_system(BlenderRNA *brna)
 	RNA_def_property_pointer_sdna(prop, NULL, "display");
 	RNA_def_property_struct_type(prop, "HairDisplaySettings");
 	RNA_def_property_ui_text(prop, "Display Settings", "Display settings for the hair system");
+
+	prop = RNA_def_property(srna, "render_iterator", PROP_POINTER, PROP_NONE);
+	RNA_def_property_struct_type(prop, "HairRenderIterator");
+	RNA_def_property_pointer_funcs(prop, "rna_HairSystem_render_get", NULL, NULL, NULL);
+	RNA_def_property_ui_text(prop, "Render Iterator", "Access to render data");
+}
+
+static void rna_def_hair_render_iterator(BlenderRNA *brna)
+{
+	StructRNA *srna;
+	FunctionRNA *func;
+	PropertyRNA *parm;
+
+	srna = RNA_def_struct(brna, "HairRenderIterator", NULL);
+	RNA_def_struct_sdna(srna, "HairRenderIterator");
+	RNA_def_struct_ui_text(srna, "Hair Render Iterator", "Iterator over rendered hairs");
+
+	func = RNA_def_function(srna, "init", "rna_HairRenderIterator_init");
+	RNA_def_function_ui_description(func, "Reset the iterator to the start of the render data");
+
+	func = RNA_def_function(srna, "end", "rna_HairRenderIterator_end");
+	RNA_def_function_ui_description(func, "Clean up the iterator after finishing render data export");
+
+	func = RNA_def_function(srna, "valid", "rna_HairRenderIterator_valid");
+	RNA_def_function_ui_description(func, "Returns True if the iterator valid elements left");
+	parm = RNA_def_boolean(func, "result", false, "Result", "");
+	RNA_def_function_return(func, parm);
+
+	func = RNA_def_function(srna, "step_init", "rna_HairRenderIterator_step_init");
+	RNA_def_function_ui_description(func, "Iterator over interpolation steps");
+	RNA_def_function_flag(func, FUNC_USE_SELF_ID);
+	parm = RNA_def_pointer(func, "result", "HairRenderStepIterator", "Result", "");
+	RNA_def_function_return(func, parm);
+	RNA_def_property_flag(parm, PROP_RNAPTR);
+}
+
+static void rna_def_hair_render_step_iterator(BlenderRNA *brna)
+{
+	static const float default_co[3] = { 0.0f, 0.0f, 0.0f };
+	
+	StructRNA *srna;
+	FunctionRNA *func;
+	PropertyRNA *parm;
+
+	srna = RNA_def_struct(brna, "HairRenderStepIterator", NULL);
+	RNA_def_struct_sdna(srna, "HairRenderIterator");
+	RNA_def_struct_ui_text(srna, "Hair Render Step Iterator", "Iterator over steps in a single hair's render data");
+
+//	func = RNA_def_function(srna, "init", "rna_HairRenderStepIterator_init");
+//	RNA_def_function_ui_description(func, "Reset the iterator to the start of the render data");
+
+	func = RNA_def_function(srna, "valid", "rna_HairRenderStepIterator_valid");
+	RNA_def_function_ui_description(func, "Returns True if the iterator valid elements left");
+	parm = RNA_def_boolean(func, "result", false, "Result", "");
+	RNA_def_function_return(func, parm);
+
+	func = RNA_def_function(srna, "next", "rna_HairRenderStepIterator_next");
+	RNA_def_function_ui_description(func, "Advance to the next interpolation step");
+
+	func = RNA_def_function(srna, "eval", "rna_HairRenderStepIterator_eval");
+	RNA_def_function_ui_description(func, "Evaluate the iterator to get hair data at the current step");
+	parm = RNA_def_float_vector(func, "co", 3, default_co, -FLT_MAX, FLT_MAX, "Location", "Location of the hair strand", -FLT_MAX, FLT_MAX);
+	RNA_def_function_output(func, parm);
+	parm = RNA_def_float(func, "radius", 0.0f, -FLT_MAX, FLT_MAX, "Radius", "Thickness of the hair wisp", -FLT_MAX, FLT_MAX);
+	RNA_def_function_output(func, parm);
 }
 
 void RNA_def_hair(BlenderRNA *brna)
 {
 	rna_def_hair_params(brna);
 	rna_def_hair_display_settings(brna);
+	rna_def_hair_render_iterator(brna);
+	rna_def_hair_render_step_iterator(brna);
 	rna_def_hair_system(brna);
 }




More information about the Bf-blender-cvs mailing list