[Bf-blender-cvs] [5a48a83] alembic_pointcache: Integration of point caching into the modifier stack.

Lukas Tönne noreply at git.blender.org
Tue Nov 4 13:49:50 CET 2014


Commit: 5a48a83663ffb4a03a63d9af95b3270988b1d006
Author: Lukas Tönne
Date:   Tue Nov 4 13:46:52 2014 +0100
Branches: alembic_pointcache
https://developer.blender.org/rB5a48a83663ffb4a03a63d9af95b3270988b1d006

Integration of point caching into the modifier stack.

This ensures that the modifier stack is disabled up to the last valid
cache modifier. This cache modifier then provides a derived mesh as
input for the remaining modifier stack tail, or as final output if no
other modifiers follow.

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

M	source/blender/blenkernel/intern/DerivedMesh.c
M	source/blender/pointcache/PTC_api.cpp
M	source/blender/pointcache/PTC_api.h
M	source/blender/pointcache/intern/reader.cpp
M	source/blender/pointcache/intern/reader.h

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

diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 81c03d8..1956a03 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -65,6 +65,8 @@
 #include "BKE_deform.h"
 #include "BKE_global.h" /* For debug flag, DM_update_tessface_data() func. */
 
+#include "PTC_api.h"
+
 #ifdef WITH_GAMEENGINE
 #include "BKE_navmesh_conversion.h"
 static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm);
@@ -1461,6 +1463,58 @@ static void dm_ensure_display_normals(DerivedMesh *dm)
 		CDDM_calc_normals_mapping_ex(dm, (dm->dirty & DM_DIRTY_NORMALS) ? false : true);
 	}
 }
+
+/* Look for last point cache modifier that provides a valid derived mesh.
+ * This will then be used as the input for remaining modifiers, or as the
+ * final result if no other modifiers follow.
+ */
+static ModifierData *mesh_find_start_modifier(Scene *scene, Object *ob, VirtualModifierData *virtual_modifiers, int required_mode, bool useDeform)
+{
+	const bool skipVirtualArmature = (useDeform < 0);
+	
+	ModifierData *md;
+	
+	for (md = ob->modifiers.last; md; md = md->prev) {
+		if (md->type == eModifierType_PointCache) {
+			PointCacheModifierData *pcmd = (PointCacheModifierData *)md;
+			struct PTCReader *reader;
+			PTCReadSampleResult result;
+			
+			if (!modifier_isEnabled(scene, md, required_mode))
+				continue;
+			
+			/* XXX needs a more lightweight reader stored inside the modifier,
+			 * which can be checked quickly for valid cache samples before reading.
+			 */
+			reader = PTC_reader_point_cache(scene, ob, pcmd);
+			result = PTC_test_sample(reader, scene->r.cfra);
+			PTC_reader_free(reader);
+			
+			if (ELEM(result, PTC_READ_SAMPLE_EXACT, PTC_READ_SAMPLE_INTERPOLATED)) {
+				break;
+			}
+		}
+	}
+	if (md)
+		return md;
+	
+	/* no valid cache modifier found,
+	 * take virtual modifiers at list start into account
+	 */
+	
+	if (!skipVirtualArmature) {
+		md = modifiers_getVirtualModifierList(ob, virtual_modifiers);
+	}
+	else {
+		/* game engine exception */
+		md = ob->modifiers.first;
+		if (md && md->type == eModifierType_Armature)
+			md = md->next;
+	}
+	
+	return md;
+}
+
 /* new value for useDeform -1  (hack for the gameengine):
  * - apply only the modifier stack of the object, skipping the virtual modifiers,
  * - don't apply the key
@@ -1482,7 +1536,6 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
 	int numVerts = me->totvert;
 	int required_mode;
 	bool isPrevDeform = false;
-	const bool skipVirtualArmature = (useDeform < 0);
 	MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
 	const bool has_multires = (mmd && mmd->sculptlvl != 0);
 	bool multires_applied = false;
@@ -1511,23 +1564,14 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
 		app_flags |= MOD_APPLY_USECACHE;
 	if (useDeform)
 		deform_app_flags |= MOD_APPLY_USECACHE;
-
-	if (!skipVirtualArmature) {
-		firstmd = modifiers_getVirtualModifierList(ob, &virtualModifierData);
-	}
-	else {
-		/* game engine exception */
-		firstmd = ob->modifiers.first;
-		if (firstmd && firstmd->type == eModifierType_Armature)
-			firstmd = firstmd->next;
-	}
-
-	md = firstmd;
-
-	modifiers_clearErrors(ob);
-
+	
 	if (useRenderParams) required_mode = eModifierMode_Render;
 	else required_mode = eModifierMode_Realtime;
+	
+	modifiers_clearErrors(ob);
+	
+	firstmd = mesh_find_start_modifier(scene, ob, &virtualModifierData, required_mode, useDeform);
+	md = firstmd;
 
 	if (do_mod_wmcol || do_mod_mcol) {
 		/* Find the last active modifier generating a preview, or NULL if none. */
diff --git a/source/blender/pointcache/PTC_api.cpp b/source/blender/pointcache/PTC_api.cpp
index ac57661..8e730e0 100644
--- a/source/blender/pointcache/PTC_api.cpp
+++ b/source/blender/pointcache/PTC_api.cpp
@@ -77,12 +77,6 @@ void PTC_reader_free(PTCReader *_reader)
 	delete reader;
 }
 
-PTCReadSampleResult PTC_read_sample(struct PTCReader *_reader, float frame)
-{
-	PTC::Reader *reader = (PTC::Reader *)_reader;
-	return reader->read_sample(frame);
-}
-
 void PTC_reader_get_frame_range(PTCReader *_reader, int *start_frame, int *end_frame)
 {
 	PTC::Reader *reader = (PTC::Reader *)_reader;
@@ -92,6 +86,18 @@ void PTC_reader_get_frame_range(PTCReader *_reader, int *start_frame, int *end_f
 	if (end_frame) *end_frame = efra;
 }
 
+PTCReadSampleResult PTC_read_sample(PTCReader *_reader, float frame)
+{
+	PTC::Reader *reader = (PTC::Reader *)_reader;
+	return reader->read_sample(frame);
+}
+
+PTCReadSampleResult PTC_test_sample(PTCReader *_reader, float frame)
+{
+	PTC::Reader *reader = (PTC::Reader *)_reader;
+	return reader->test_sample(frame);
+}
+
 /* get writer/reader from RNA type */
 PTCWriter *PTC_writer_from_rna(Scene *scene, PointerRNA *ptr)
 {
diff --git a/source/blender/pointcache/PTC_api.h b/source/blender/pointcache/PTC_api.h
index c60138a..1861e1d 100644
--- a/source/blender/pointcache/PTC_api.h
+++ b/source/blender/pointcache/PTC_api.h
@@ -57,8 +57,9 @@ void PTC_writer_free(struct PTCWriter *writer);
 void PTC_write_sample(struct PTCWriter *writer);
 
 void PTC_reader_free(struct PTCReader *reader);
-PTCReadSampleResult PTC_read_sample(struct PTCReader *reader, float frame);
 void PTC_reader_get_frame_range(struct PTCReader *reader, int *start_frame, int *end_frame);
+PTCReadSampleResult PTC_read_sample(struct PTCReader *reader, float frame);
+PTCReadSampleResult PTC_test_sample(struct PTCReader *reader, float frame);
 
 /* get writer/reader from RNA type */
 struct PTCWriter *PTC_writer_from_rna(struct Scene *scene, struct PointerRNA *ptr);
diff --git a/source/blender/pointcache/intern/reader.cpp b/source/blender/pointcache/intern/reader.cpp
index b6a8a74..e54926a 100644
--- a/source/blender/pointcache/intern/reader.cpp
+++ b/source/blender/pointcache/intern/reader.cpp
@@ -62,4 +62,29 @@ ISampleSelector Reader::get_frame_sample_selector(float frame)
 	return ISampleSelector(frame_to_time(frame), ISampleSelector::kFloorIndex);
 }
 
+PTCReadSampleResult Reader::test_sample(float frame)
+{
+	if (m_archive.valid()) {
+		double start_time, end_time;
+		GetArchiveStartAndEndTime(m_archive, start_time, end_time);
+		float start_frame = time_to_frame(start_time);
+		float end_frame = time_to_frame(end_time);
+		
+		if (frame < start_frame)
+			return PTC_READ_SAMPLE_EARLY;
+		else if (frame > end_frame)
+			return PTC_READ_SAMPLE_LATE;
+		else {
+			/* TODO could also be EXACT, but INTERPOLATED is more general
+			 * do we need to support this?
+			 * checking individual time samplings is also possible, but more involved.
+			 */
+			return PTC_READ_SAMPLE_INTERPOLATED;
+		}
+	}
+	else {
+		return PTC_READ_SAMPLE_INVALID;
+	}
+}
+
 } /* namespace PTC */
diff --git a/source/blender/pointcache/intern/reader.h b/source/blender/pointcache/intern/reader.h
index 8ee27bc..3b2bd1d 100644
--- a/source/blender/pointcache/intern/reader.h
+++ b/source/blender/pointcache/intern/reader.h
@@ -43,6 +43,7 @@ public:
 	void get_frame_range(int &start_frame, int &end_frame);
 	Abc::ISampleSelector get_frame_sample_selector(float frame);
 	
+	PTCReadSampleResult test_sample(float frame);
 	virtual PTCReadSampleResult read_sample(float frame) = 0;
 	
 protected:




More information about the Bf-blender-cvs mailing list