[Bf-blender-cvs] [bfe9fc2] alembic: Extended Cycles to support both parent and child strands.

Lukas Tönne noreply at git.blender.org
Thu Apr 9 12:14:12 CEST 2015


Commit: bfe9fc218d2a5d7201803b381da5dfe1b0491b0b
Author: Lukas Tönne
Date:   Thu Apr 9 12:11:37 2015 +0200
Branches: alembic
https://developer.blender.org/rBbfe9fc218d2a5d7201803b381da5dfe1b0491b0b

Extended Cycles to support both parent and child strands.

The code for syncing Strands and StrandsChildren data to Cycles curves
is almost identical, so to avoid code duplication a little templated
traits type has been defined, which provides the appropriate accessors
for both cases. This is very local and should not be too confusing.

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

M	intern/cycles/blender/blender_curves.cpp
M	source/blender/makesrna/intern/rna_object.c
M	source/blender/makesrna/intern/rna_strands.c

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

diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp
index 28c11ec..ae8ffd8 100644
--- a/intern/cycles/blender/blender_curves.cpp
+++ b/intern/cycles/blender/blender_curves.cpp
@@ -270,20 +270,92 @@ static void ObtainCacheParticleVcol(Mesh */*mesh*/, BL::Object /*b_ob*/, BL::Mes
 	}
 }
 
-static void ObtainCacheStrandsData(Mesh *mesh, BL::Scene b_scene, BL::Object b_parent, BL::DupliObject b_dupli_ob, BL::ParticleSystem b_psys, const Transform &/*itfm*/,
+/* A little bit of templated code here to avoid much duplication for parent/child strands:
+ * Most attributes are the same for both types, but some are handled slightly differently.
+ * These attributes are handled by templated utility functions that automatically get selected by type.
+ */
+template <typename StrandsT>
+struct StrandsTraits;
+
+template<>
+struct StrandsTraits<BL::Strands>
+{
+	typedef BL::StrandsCurve curve_t;
+	typedef BL::StrandsVertex vertex_t;
+	
+	static BL::Strands make_strands(BL::Scene b_scene, BL::Object b_parent, BL::DupliObject b_dupli_ob, BL::ParticleSystem b_psys, bool background)
+	{
+		int settings = background ? 2 : 1;
+		return b_dupli_ob.strands_new(b_scene, b_parent, b_psys, settings);
+	}
+	static void free_strands(BL::DupliObject b_dupli_ob, BL::Strands b_strands)
+	{
+		b_dupli_ob.strands_free(b_strands);
+	}
+	
+	static float3 get_location(BL::Strands b_strands, int index)
+	{
+		float *co = (b_strands.has_motion_state())? b_strands.motion_state[index].location() : b_strands.vertices[index].location();
+		return make_float3(co[0], co[1], co[2]);
+	}
+	static float3 get_uv(BL::Strands /*b_strands*/, int /*index*/, int /*uv_num*/)
+	{
+		return make_float3(0.0f, 0.0f, 0.0f);
+	}
+	static float3 get_vcol(BL::Strands /*b_strands*/, int /*index*/, int /*vcol_num*/)
+	{
+		return make_float3(0.0f, 0.0f, 0.0f);
+	}
+};
+
+template<>
+struct StrandsTraits<BL::StrandsChildren>
+{
+	typedef BL::StrandsChildCurve curve_t;
+	typedef BL::StrandsChildVertex vertex_t;
+	
+	static BL::StrandsChildren make_strands(BL::Scene b_scene, BL::Object b_parent, BL::DupliObject b_dupli_ob, BL::ParticleSystem b_psys, bool background)
+	{
+		int settings = background ? 2 : 1;
+		return b_dupli_ob.strands_children_new(b_scene, b_parent, b_psys, settings);
+	}
+	static void free_strands(BL::DupliObject b_dupli_ob, BL::StrandsChildren b_strands)
+	{
+		b_dupli_ob.strands_children_free(b_strands);
+	}
+	
+	static float3 get_location(BL::StrandsChildren b_strands, int index)
+	{
+		float *co = b_strands.vertices[index].location();
+		return make_float3(co[0], co[1], co[2]);
+	}
+	static float3 get_uv(BL::StrandsChildren /*b_strands*/, int /*index*/, int /*uv_num*/)
+	{
+		return make_float3(0.0f, 0.0f, 0.0f);
+	}
+	static float3 get_vcol(BL::StrandsChildren /*b_strands*/, int /*index*/, int /*vcol_num*/)
+	{
+		return make_float3(0.0f, 0.0f, 0.0f);
+	}
+};
+
+template <typename StrandsT>
+static bool ObtainCacheStrandsData(Mesh *mesh, BL::Scene b_scene, BL::Object b_parent, BL::DupliObject b_dupli_ob, BL::ParticleSystem b_psys, const Transform &/*itfm*/,
                                    ParticleCurveData *CData, bool background, int &keyno, int &curvenum)
 {
+	typedef StrandsTraits<StrandsT> traits;
+	typedef typename traits::curve_t CurveT;
+	
+	StrandsT b_strands = traits::make_strands(b_scene, b_parent, b_dupli_ob, b_psys, background);
+	if (!b_strands)
+		return false;
+	
 	BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
 	PointerRNA cpsys = RNA_pointer_get(&b_part.ptr, "cycles");
 	
 	int mi = clamp(b_part.material()-1, 0, mesh->used_shaders.size()-1);
 	int shader = mesh->used_shaders[mi];
 
-	int settings = background ? 2 : 1;
-	BL::Strands b_strands = b_dupli_ob.strands_new(b_scene, b_parent, b_psys, settings);
-	if (!b_strands)
-		return;
-
 	int totcurves = b_strands.curves.length();
 	int totvert = b_strands.vertices.length();
 
@@ -304,12 +376,10 @@ static void ObtainCacheStrandsData(Mesh *mesh, BL::Scene b_scene, BL::Object b_p
 	CData->curvekey_co.reserve(CData->curvekey_co.size() + totvert);
 	CData->curvekey_time.reserve(CData->curvekey_time.size() + totvert);
 
-	bool has_motion_state = b_strands.has_motion_state();
-
 	int icurve = 0;
 	int ivert = 0;
 	for(; icurve < totcurves; ++icurve) {
-		BL::StrandsCurve b_curve = b_strands.curves[icurve];
+		CurveT b_curve = b_strands.curves[icurve];
 		int numverts = b_curve.size();
 		int usedverts = 0;
 		CData->curve_firstkey.push_back(keyno);
@@ -317,8 +387,7 @@ static void ObtainCacheStrandsData(Mesh *mesh, BL::Scene b_scene, BL::Object b_p
 		float curve_length = 0.0f;
 		float3 pcKey;
 		for(int cvert = 0; cvert < numverts; ++cvert, ++ivert) {
-			float *co = (has_motion_state)? b_strands.motion_state[ivert].location() : b_strands.vertices[ivert].location();
-			float3 cKey = make_float3(co[0], co[1], co[2]);
+			float3 cKey = traits::get_location(b_strands, ivert);
 			
 			if(cvert > 0) {
 				float step_length = len(cKey - pcKey);
@@ -338,18 +407,21 @@ static void ObtainCacheStrandsData(Mesh *mesh, BL::Scene b_scene, BL::Object b_p
 		curvenum++;
 	}
 	
-	b_dupli_ob.strands_free(b_strands);
+	traits::free_strands(b_dupli_ob, b_strands);
+	return true;
 }
 
-static void ObtainCacheStrandsUV(Mesh */*mesh*/, BL::Scene b_scene, BL::Object b_parent, BL::DupliObject b_dupli_ob, BL::ParticleSystem b_psys,
-                                 ParticleCurveData *CData, bool background, int /*uv_num*/)
+template <typename StrandsT>
+static bool ObtainCacheStrandsUV(Mesh */*mesh*/, BL::Scene b_scene, BL::Object b_parent, BL::DupliObject b_dupli_ob, BL::ParticleSystem b_psys,
+                                 ParticleCurveData *CData, bool background, int uv_num)
 {
-//	BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
-
-	int settings = background ? 2 : 1;
-	BL::Strands b_strands = b_dupli_ob.strands_new(b_scene, b_parent, b_psys, settings);
+	typedef StrandsTraits<StrandsT> traits;
+	
+	StrandsT b_strands = traits::make_strands(b_scene, b_parent, b_dupli_ob, b_psys, background);
 	if (!b_strands)
-		return;
+		return false;
+	
+//	BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
 
 	int totcurves = b_strands.curves.length();
 
@@ -357,25 +429,24 @@ static void ObtainCacheStrandsUV(Mesh */*mesh*/, BL::Scene b_scene, BL::Object b
 
 	int icurve = 0;
 	for(; icurve < totcurves; ++icurve) {
-//		BL::StrandsCurve b_curve = b_strands.curves[icurve];
-		/* XXX for parent strand curves there are no UVs or VCols,
-		 * this is only supported for child curves currently
-		 */
-		CData->curve_uv.push_back(make_float3(0.0f, 0.0f, 0.0f));
+		CData->curve_uv.push_back(traits::get_uv(b_strands, icurve, uv_num));
 	}
 	
-	b_dupli_ob.strands_free(b_strands);
+	traits::free_strands(b_dupli_ob, b_strands);
+	return true;
 }
 
-static void ObtainCacheStrandsVcol(Mesh */*mesh*/, BL::Scene b_scene, BL::Object b_parent, BL::DupliObject b_dupli_ob, BL::ParticleSystem b_psys,
-                                   ParticleCurveData *CData, bool background, int /*vcol_num*/)
+template <typename StrandsT>
+static bool ObtainCacheStrandsVcol(Mesh */*mesh*/, BL::Scene b_scene, BL::Object b_parent, BL::DupliObject b_dupli_ob, BL::ParticleSystem b_psys,
+                                   ParticleCurveData *CData, bool background, int vcol_num)
 {
-//	BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
+	typedef StrandsTraits<StrandsT> traits;
 	
-	int settings = background ? 2 : 1;
-	BL::Strands b_strands = b_dupli_ob.strands_new(b_scene, b_parent, b_psys, settings);
+	StrandsT b_strands = traits::make_strands(b_scene, b_parent, b_dupli_ob, b_psys, background);
 	if (!b_strands)
-		return;
+		return false;
+	
+//	BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
 	
 	int totcurves = b_strands.curves.length();
 	
@@ -383,14 +454,11 @@ static void ObtainCacheStrandsVcol(Mesh */*mesh*/, BL::Scene b_scene, BL::Object
 	
 	int icurve = 0;
 	for(; icurve < totcurves; ++icurve) {
-	//	BL::StrandsCurve b_curve = b_strands.curves[icurve];
-		/* XXX for parent strand curves there are no UVs or VCols,
-		 * this is only supported for child curves currently
-		 */
-		CData->curve_vcol.push_back(make_float3(0.0f, 0.0f, 0.0f));
+		CData->curve_vcol.push_back(traits::get_vcol(b_strands, icurve, vcol_num));
 	}
 	
-	b_dupli_ob.strands_free(b_strands);
+	traits::free_strands(b_dupli_ob, b_strands);
+	return true;
 }
 
 bool ObtainCacheCurvesData(Mesh *mesh, BL::Scene b_scene, BL::Mesh b_mesh, BL::Object b_parent, BL::DupliObject b_dupli_ob,
@@ -414,8 +482,16 @@ bool ObtainCacheCurvesData(Mesh *mesh, BL::Scene b_scene, BL::Mesh b_mesh, BL::O
 			BL::ParticleSettings b_part((const PointerRNA)b_psys.settings().ptr);
 
 			if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
-				if (b_dupli_ob && b_parent)
-					ObtainCacheStrandsData(mesh, b_scene, b_parent, b_dupli_ob, b_psys, itfm, CData, background, keyno, curvenum);
+				if (b_dupli_ob && b_parent) {
+					if (ObtainCacheStrandsData<BL::StrandsChildren>(mesh, b_scene, b_parent, b_dupli_ob, b_psys, itfm, CData, background, keyno, curvenum));
+						/* use child strands cache */
+					else if (ObtainCacheStrandsData<BL::Strands>(mesh, b_scene, b_parent, b_dupli_ob, b_psys, itfm, CData, background, keyno, curvenum));
+						/* use parent strands cache */
+					else {
+						/* use object data */
+						ObtainCacheParticleData(mesh, b_ob, b_psys, itfm, CData, background, keyno, curvenum);
+					}
+				}
 				else
 					ObtainCacheParticleData(mesh, b_ob, b_psys, itfm, CData, background, keyno, curvenum);
 			}
@@ -444,7 +520,14 @@ bool ObtainCacheCurvesUV(Mesh *mesh, BL::Scene b_scene, BL::Mesh b_mesh, BL::Obj
 
 			if((b_part.render_type() == BL::ParticleSettings::render_type_PATH) && (b_part.type() == BL::ParticleSettings::type_HAIR)) {
 				if (b_dupli_ob && b_parent)
-					ObtainCacheStrandsUV(mesh, b_scene, b_parent, b_dupli_ob, b_psys, CData, background, uv_num);
+					if (ObtainCacheStrandsUV<BL::StrandsChildren>(mesh, b_scene, b_parent, b_dupli_ob, b_psys, CData, background, uv_num));
+						/* use child 

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list