[Bf-blender-cvs] [ec2fea733bd] blender2.8: Make object point cache iteration more generic

Sergey Sharybin noreply at git.blender.org
Wed Nov 14 14:09:19 CET 2018


Commit: ec2fea733bda8c83ef1e7585ff5d99ce7407fb25
Author: Sergey Sharybin
Date:   Tue Nov 13 17:48:00 2018 +0100
Branches: blender2.8
https://developer.blender.org/rBec2fea733bda8c83ef1e7585ff5d99ce7407fb25

Make object point cache iteration more generic

Currently should be no functional changes, but this will
simplify implementing some incoming logic.

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

M	source/blender/blenkernel/intern/pointcache.c

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

diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 99451a7b6c1..60defc575f4 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1672,88 +1672,161 @@ PTCacheID BKE_ptcache_id_find(Object *ob, Scene *scene, PointCache *cache)
 	return result;
 }
 
-void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int duplis)
-{
-	PTCacheID *pid;
-	ParticleSystem *psys;
-	ModifierData *md;
-
-	lb->first= lb->last= NULL;
-
-	if (ob->soft) {
-		pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
-		BKE_ptcache_id_from_softbody(pid, ob, ob->soft);
-		BLI_addtail(lb, pid);
-	}
+/* Callback which is used by point cache foreach() family of functions.
+ *
+ * Receives ID of the point cache.
+ *
+ * NOTE: This ID is owned by foreach() routines and can not be used outside of
+ * the foreach loop. This means that if one wants to store them those are to be
+ * malloced and copied over.
+ *
+ * If the function returns false, then foreach() loop aborts.
+ */
+typedef bool (*ForeachPtcacheCb)(PTCacheID *pid, void *userdata);
 
-	for (psys=ob->particlesystem.first; psys; psys=psys->next) {
-		if (psys->part==NULL)
+static bool foreach_object_particle_ptcache(Object *object,
+                                            ForeachPtcacheCb callback,
+                                            void *callback_user_data)
+{
+	PTCacheID pid;
+	for (ParticleSystem *psys = object->particlesystem.first;
+	     psys != NULL;
+	     psys = psys->next)
+	{
+		if (psys->part==NULL) {
 			continue;
-
-		/* check to make sure point cache is actually used by the particles */
-		if (ELEM(psys->part->phystype, PART_PHYS_NO, PART_PHYS_KEYED))
+		}
+		/* Check to make sure point cache is actually used by the particles. */
+		if (ELEM(psys->part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) {
 			continue;
-
-		/* hair needs to be included in id-list for cache edit mode to work */
-		/* if (psys->part->type == PART_HAIR && (psys->flag & PSYS_HAIR_DYNAMICS)==0) */
-		/*	continue; */
-
-		if (psys->part->type == PART_FLUID)
+		}
+		/* Hair needs to be included in id-list for cache edit mode to work. */
+#if 0
+		if ((psys->part->type == PART_HAIR) &&
+		    (psys->flag & PSYS_HAIR_DYNAMICS) == 0)
+		{
 			continue;
-
-		pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
-		BKE_ptcache_id_from_particles(pid, ob, psys);
-		BLI_addtail(lb, pid);
+		}
+#endif
+		if (psys->part->type == PART_FLUID) {
+			continue;
+		}
+		BKE_ptcache_id_from_particles(&pid, object, psys);
+		if (!callback(&pid, callback_user_data)) {
+			return false;
+		}
 	}
+	return true;
+}
 
-	for (md=ob->modifiers.first; md; md=md->next) {
+static bool foreach_object_modifier_ptcache(Object *object,
+                                            ForeachPtcacheCb callback,
+                                            void *callback_user_data)
+{
+	PTCacheID pid;
+	for (ModifierData *md = object->modifiers.first; md != NULL; md = md->next) {
 		if (md->type == eModifierType_Cloth) {
-			pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
-			BKE_ptcache_id_from_cloth(pid, ob, (ClothModifierData*)md);
-			BLI_addtail(lb, pid);
+			BKE_ptcache_id_from_cloth(&pid, object, (ClothModifierData*)md);
+			if (!callback(&pid, callback_user_data)) {
+				return false;
+			}
 		}
 		else if (md->type == eModifierType_Smoke) {
 			SmokeModifierData *smd = (SmokeModifierData *)md;
 			if (smd->type & MOD_SMOKE_TYPE_DOMAIN) {
-				pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
-				BKE_ptcache_id_from_smoke(pid, ob, (SmokeModifierData*)md);
-				BLI_addtail(lb, pid);
+				BKE_ptcache_id_from_smoke(&pid, object, (SmokeModifierData*)md);
+				if (!callback(&pid, callback_user_data)) {
+					return false;
+				}
 			}
 		}
 		else if (md->type == eModifierType_DynamicPaint) {
 			DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md;
 			if (pmd->canvas) {
 				DynamicPaintSurface *surface = pmd->canvas->surfaces.first;
-
 				for (; surface; surface=surface->next) {
-					pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
-					BKE_ptcache_id_from_dynamicpaint(pid, ob, surface);
-					BLI_addtail(lb, pid);
+					BKE_ptcache_id_from_dynamicpaint(&pid, object, surface);
+					if (!callback(&pid, callback_user_data)) {
+						return false;
+					}
 				}
 			}
 		}
 	}
+	return true;
+}
 
-	if (scene && ob->rigidbody_object && scene->rigidbody_world) {
-		pid = MEM_callocN(sizeof(PTCacheID), "PTCacheID");
-		BKE_ptcache_id_from_rigidbody(pid, ob, scene->rigidbody_world);
-		BLI_addtail(lb, pid);
+/* Return false if any of callbacks returned false. */
+static bool foreach_object_ptcache(Scene *scene,
+                                   Object *object,
+                                   int duplis,
+                                   ForeachPtcacheCb callback,
+                                   void *callback_user_data)
+{
+	PTCacheID pid;
+	/* Soft body. */
+	if (object->soft != NULL) {
+		BKE_ptcache_id_from_softbody(&pid, object, object->soft);
+		if (!callback(&pid, callback_user_data)) {
+			return false;
+		}
+	}
+	/* Particle systems. */
+	if (!foreach_object_particle_ptcache(object, callback, callback_user_data)) {
+		return false;
+	}
+	/* Modifiers. */
+	if (!foreach_object_modifier_ptcache(object, callback, callback_user_data)) {
+		return false;
+	}
+	/* Rigid body. */
+	if (scene != NULL &&
+	    object->rigidbody_object != NULL &&
+	    scene->rigidbody_world != NULL)
+	{
+		BKE_ptcache_id_from_rigidbody(&pid, object, scene->rigidbody_world);
+		if (!callback(&pid, callback_user_data)) {
+			return false;
+		}
 	}
-
 	/* Consider all object in dupli groups to be part of the same object,
 	 * for baking with linking dupligroups. Once we have better overrides
 	 * this can be revisited so users select the local objects directly. */
-	if (scene && (duplis-- > 0) && (ob->dup_group)) {
-		FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(ob->dup_group, object)
+	if (scene != NULL && (duplis-- > 0) && (object->dup_group != NULL)) {
+		FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(object->dup_group,
+		                                          current_object)
 		{
-			if (object != ob) {
-				ListBase lb_dupli_pid;
-				BKE_ptcache_ids_from_object(&lb_dupli_pid, object, scene, duplis);
-				BLI_movelisttolist(lb, &lb_dupli_pid);
+			if (current_object == object) {
+				continue;
 			}
+			foreach_object_ptcache(
+			        scene, object, duplis, callback, callback_user_data);
 		}
 		FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
 	}
+	return true;
+}
+
+typedef struct PTCacheIDsFromObjectData {
+	ListBase *list_base;
+} PTCacheIDsFromObjectData;
+
+static bool ptcache_ids_from_object_cb(PTCacheID *pid, void *userdata)
+{
+	PTCacheIDsFromObjectData *data = userdata;
+	PTCacheID *own_pid = MEM_mallocN(sizeof(PTCacheID), "PTCacheID");
+	*own_pid = *pid;
+	BLI_addtail(data->list_base, own_pid);
+	return true;
+}
+
+void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int duplis)
+{
+	PTCacheIDsFromObjectData data;
+	lb->first = lb->last = NULL;
+	data.list_base = lb;
+	foreach_object_ptcache(
+	        scene, ob, duplis, ptcache_ids_from_object_cb, &data);
 }
 
 /* File handling */



More information about the Bf-blender-cvs mailing list