[Bf-blender-cvs] [4b2fbeb] alembic_pointcache: Support for writing derived mesh data from point cache modifier between other modifiers.

Lukas Tönne noreply at git.blender.org
Tue Nov 4 16:30:12 CET 2014


Commit: 4b2fbebc27c72c374caba1406e09e76a009eaf8d
Author: Lukas Tönne
Date:   Tue Nov 4 16:27:48 2014 +0100
Branches: alembic_pointcache
https://developer.blender.org/rB4b2fbebc27c72c374caba1406e09e76a009eaf8d

Support for writing derived mesh data from point cache modifier between
other modifiers.

Previously this was simply using the derivedFinal of the object. Now
the point cache has its own writer instance which is writing samples
during the regular modifier evaluation, rather than directly being
called by the bake operator.

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

M	source/blender/editors/physics/physics_pointcache.c
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/modifiers/intern/MOD_pointcache.c
M	source/blender/pointcache/PTC_api.cpp
M	source/blender/pointcache/PTC_api.h
M	source/blender/pointcache/intern/export.cpp
M	source/blender/pointcache/intern/mesh.cpp

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

diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c
index 25a1c68..f9b6135 100644
--- a/source/blender/editors/physics/physics_pointcache.c
+++ b/source/blender/editors/physics/physics_pointcache.c
@@ -37,6 +37,7 @@
 #include "BLI_blenlib.h"
 #include "BLI_utildefines.h"
 
+#include "DNA_modifier_types.h"
 #include "DNA_scene_types.h"
 
 #include "BKE_context.h"
@@ -75,6 +76,7 @@ typedef struct PTCacheExportJob {
 	struct Scene *scene;
 	EvaluationContext eval_ctx;
 	
+	PointerRNA user_ptr;
 	struct PointCache *cache;
 	struct PTCWriter *writer;
 	
@@ -124,7 +126,15 @@ static void ptcache_export_endjob(void *customdata)
 	BKE_spacedata_draw_locks(false);
 	
 	/* free the cache writer (closes output file) */
-	PTC_writer_free(data->writer);
+	if (RNA_struct_is_a(data->user_ptr.type, &RNA_PointCacheModifier)) {
+		PointCacheModifierData *pcmd = (PointCacheModifierData *)data->user_ptr.data;
+		
+		PTC_writer_free(pcmd->writer);
+		pcmd->writer = NULL;
+	}
+	else {
+		PTC_writer_free(data->writer);
+	}
 	
 	/* reset scene frame */
 	scene->r.cfra = data->origfra;
@@ -139,7 +149,7 @@ static int ptcache_export_exec(bContext *C, wmOperator *op)
 	Main *bmain = CTX_data_main(C);
 	Scene *scene = CTX_data_scene(C);
 	PointCache *cache = ptcache_ptr.data;
-	struct PTCWriter *writer;
+	struct PTCWriter *writer = NULL;
 	PTCacheExportJob *data;
 	wmJob *wm_job;
 	
@@ -147,10 +157,22 @@ static int ptcache_export_exec(bContext *C, wmOperator *op)
 		BKE_reportf(op->reports, RPT_ERROR_INVALID_INPUT, "Missing point cache user info");
 		return OPERATOR_CANCELLED;
 	}
-	writer = PTC_writer_from_rna(scene, &user_ptr);
-	if (!writer) {
-		BKE_reportf(op->reports, RPT_ERROR_INVALID_INPUT, "%s is not a valid point cache user type", RNA_struct_identifier(user_ptr.type));
-		return OPERATOR_CANCELLED;
+	
+	/* special case: point cache modifier uses internal writer
+	 * and needs to be set up for baking.
+	 */
+	if (RNA_struct_is_a(user_ptr.type, &RNA_PointCacheModifier)) {
+		Object *ob = (Object *)user_ptr.id.data;
+		PointCacheModifierData *pcmd = (PointCacheModifierData *)user_ptr.data;
+		
+		pcmd->writer = PTC_writer_point_cache(scene, ob, pcmd);
+	}
+	else {
+		writer = PTC_writer_from_rna(scene, &user_ptr);
+		if (!writer) {
+			BKE_reportf(op->reports, RPT_ERROR_INVALID_INPUT, "%s is not a valid point cache user type", RNA_struct_identifier(user_ptr.type));
+			return OPERATOR_CANCELLED;
+		}
 	}
 	
 	/* XXX annoying hack: needed to prevent data corruption when changing
@@ -169,6 +191,7 @@ static int ptcache_export_exec(bContext *C, wmOperator *op)
 	data = MEM_callocN(sizeof(PTCacheExportJob), "Point Cache Export Job");
 	data->bmain = bmain;
 	data->scene = scene;
+	data->user_ptr = user_ptr;
 	data->cache = cache;
 	data->writer = writer;
 	
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 63c2f05..72e24e3 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -1375,6 +1375,9 @@ typedef struct PointCacheModifierData {
 	int pad;
 	
 	struct PointCache *point_cache;
+	
+	struct PTCWriter *writer;
+	struct DerivedMesh *output_dm;
 } PointCacheModifierData;
 
 
diff --git a/source/blender/modifiers/intern/MOD_pointcache.c b/source/blender/modifiers/intern/MOD_pointcache.c
index 57ff83d..d8576ee 100644
--- a/source/blender/modifiers/intern/MOD_pointcache.c
+++ b/source/blender/modifiers/intern/MOD_pointcache.c
@@ -25,15 +25,16 @@
  */
 
 #include <stdio.h>
+#include <stdlib.h>
+
+#include "BLI_utildefines.h"
+#include "BLI_string.h"
 
 #include "DNA_scene_types.h"
 #include "DNA_object_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 
-#include "BLI_utildefines.h"
-#include "BLI_string.h"
-
 #include "BKE_cdderivedmesh.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_scene.h"
@@ -76,31 +77,58 @@ static void freeData(ModifierData *md)
 	BKE_ptcache_free(pcmd->point_cache);
 }
 
-static bool dependsOnTime(ModifierData *UNUSED(md))
+typedef enum ePointCacheModifierMode {
+	MOD_POINTCACHE_READ,
+	MOD_POINTCACHE_WRITE,
+} ePointCacheModifierMode;
+
+static ePointCacheModifierMode getMode(PointCacheModifierData *pcmd)
+{
+	if (pcmd->writer)
+		return MOD_POINTCACHE_WRITE;
+	else
+		return MOD_POINTCACHE_READ;
+}
+
+static bool dependsOnTime(ModifierData *md)
 {
-	return true;
+	PointCacheModifierData *pcmd = (PointCacheModifierData *)md;
+	
+	/* considered time-dependent when reading from cache file */
+	/* TODO check cache frame range here to optimize */
+	return getMode(pcmd) == MOD_POINTCACHE_READ;
 }
 
 static DerivedMesh *pointcache_do(PointCacheModifierData *pcmd, Object *ob, DerivedMesh *dm)
 {
 	Scene *scene = pcmd->modifier.scene;
 	const float cfra = BKE_scene_frame_get(scene);
+	const ePointCacheModifierMode mode = getMode(pcmd);
 	
 	DerivedMesh *finaldm = dm;
 
-	struct PTCReader *reader = PTC_reader_point_cache(scene, ob, pcmd);
-	
-	if (PTC_read_sample(reader, cfra) == PTC_READ_SAMPLE_INVALID) {
-		modifier_setError(&pcmd->modifier, "%s", "Cannot read Alembic cache file");
+	if (mode == MOD_POINTCACHE_WRITE) {
+		BLI_assert(pcmd->writer != NULL);
+		
+		pcmd->output_dm = dm;
+		PTC_write_sample(pcmd->writer);
+		pcmd->output_dm = NULL;
 	}
-	else {
-		DerivedMesh *result = PTC_reader_point_cache_acquire_result(reader);
-		if (result)
-			finaldm = result;
+	else if (mode == MOD_POINTCACHE_READ) {
+		struct PTCReader *reader = PTC_reader_point_cache(scene, ob, pcmd);
+		
+		if (PTC_read_sample(reader, cfra) == PTC_READ_SAMPLE_INVALID) {
+			modifier_setError(&pcmd->modifier, "%s", "Cannot read cache file");
+		}
+		else {
+			DerivedMesh *result = PTC_reader_point_cache_acquire_result(reader);
+			if (result)
+				finaldm = result;
+		}
+		
+		PTC_reader_free(reader);
 	}
 	
-	PTC_reader_free(reader);
-	
 	return finaldm;
 }
 
diff --git a/source/blender/pointcache/PTC_api.cpp b/source/blender/pointcache/PTC_api.cpp
index 8e730e0..29a0522 100644
--- a/source/blender/pointcache/PTC_api.cpp
+++ b/source/blender/pointcache/PTC_api.cpp
@@ -131,11 +131,13 @@ PTCWriter *PTC_writer_from_rna(Scene *scene, PointerRNA *ptr)
 		DynamicPaintSurface *surface = (DynamicPaintSurface *)ptr->data;
 		return PTC_writer_dynamicpaint(scene, ob, surface);
 	}
+#if 0 /* modifier uses internal writer during scene update */
 	if (RNA_struct_is_a(ptr->type, &RNA_PointCacheModifier)) {
 		Object *ob = (Object *)ptr->id.data;
 		PointCacheModifierData *pcmd = (PointCacheModifierData *)ptr->data;
 		return PTC_writer_point_cache(scene, ob, pcmd);
 	}
+#endif
 	return NULL;
 }
 
diff --git a/source/blender/pointcache/PTC_api.h b/source/blender/pointcache/PTC_api.h
index 1861e1d..217474c 100644
--- a/source/blender/pointcache/PTC_api.h
+++ b/source/blender/pointcache/PTC_api.h
@@ -50,7 +50,6 @@ void PTC_invalidate(struct PointCache *cache);
 void PTC_bake(struct Main *bmain, struct Scene *scene, struct EvaluationContext *evalctx, struct PTCWriter *writer, int start_frame, int end_frame,
               short *stop, short *do_update, float *progress);
 
-
 /*** Reader/Writer Interface ***/
 
 void PTC_writer_free(struct PTCWriter *writer);
diff --git a/source/blender/pointcache/intern/export.cpp b/source/blender/pointcache/intern/export.cpp
index 57125f8..b7df496 100644
--- a/source/blender/pointcache/intern/export.cpp
+++ b/source/blender/pointcache/intern/export.cpp
@@ -49,7 +49,8 @@ void Exporter::bake(Writer *writer, int start_frame, int end_frame)
 		m_scene->r.cfra = cfra;
 		BKE_scene_update_for_newframe(m_evalctx, m_bmain, m_scene, m_scene->lay);
 
-		writer->write_sample();
+		if (writer)
+			writer->write_sample();
 
 		set_progress((float)(cfra - start_frame + 1) / (float)(end_frame - start_frame + 1));
 
diff --git a/source/blender/pointcache/intern/mesh.cpp b/source/blender/pointcache/intern/mesh.cpp
index 119f6b6..2b3de1f 100644
--- a/source/blender/pointcache/intern/mesh.cpp
+++ b/source/blender/pointcache/intern/mesh.cpp
@@ -54,18 +54,18 @@ PointCacheWriter::~PointCacheWriter()
 
 void PointCacheWriter::write_sample()
 {
-	DerivedMesh *source_dm = m_ob->derivedFinal;
-	if (!source_dm)
+	DerivedMesh *output_dm = m_pcmd->output_dm;
+	if (!output_dm)
 		return;
 	
 	OPolyMeshSchema &schema = m_mesh.getSchema();
 	
-	MVert *mv, *mverts = source_dm->getVertArray(source_dm);
-	MLoop *ml, *mloops = source_dm->getLoopArray(source_dm);
-	MPoly *mp, *mpolys = source_dm->getPolyArray(source_dm);
-	int totvert = source_dm->getNumVerts(source_dm);
-	int totloop = source_dm->getNumLoops(source_dm);
-	int totpoly = source_dm->getNumPolys(source_dm);
+	MVert *mv, *mverts = output_dm->getVertArray(output_dm);
+	MLoop *ml, *mloops = output_dm->getLoopArray(output_dm);
+	MPoly *mp, *mpolys = output_dm->getPolyArray(output_dm);
+	int totvert = output_dm->getNumVerts(output_dm);
+	int totloop = output_dm->getNumLoops(output_dm);
+	int totpoly = output_dm->getNumPolys(output_dm);
 	int i;
 	
 	std::vector<V3f> positions;
@@ -122,6 +122,8 @@ PTCReadSampleResult PointCacheReader::read_sample(float frame)
 	
 	IPolyMeshSchema &schema = m_mesh.getSchema();
 //	TimeSamplingPtr ts = schema.getTimeSampling();
+	if (!schema.valid() || schema.getPositionsProperty().getNumSamples() == 0)
+		return PTC_READ_SAMPLE_INVALID;
 	
 	ISampleSelector ss = get_frame_sample_selector(frame);
 //	chrono_t time = ss.getRequestedTime();




More information about the Bf-blender-cvs mailing list