[Bf-blender-cvs] [9a2176f] alembic: Write basic hair curves to caches for dupli groups.

Lukas Tönne noreply at git.blender.org
Thu Mar 26 13:55:21 CET 2015


Commit: 9a2176f1152b8212aa4e0016fa40d1c4d2d92251
Author: Lukas Tönne
Date:   Tue Mar 24 12:57:30 2015 +0100
Branches: alembic
https://developer.blender.org/rB9a2176f1152b8212aa4e0016fa40d1c4d2d92251

Write basic hair curves to caches for dupli groups.

This data will be used for dupli simulations later on. Child path
generation could also be done based on this data without involvement of
particle systems.

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

M	source/blender/pointcache/alembic/abc_group.cpp
M	source/blender/pointcache/alembic/abc_object.cpp
M	source/blender/pointcache/alembic/abc_object.h
M	source/blender/pointcache/alembic/abc_particles.cpp
M	source/blender/pointcache/alembic/abc_particles.h

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

diff --git a/source/blender/pointcache/alembic/abc_group.cpp b/source/blender/pointcache/alembic/abc_group.cpp
index 1f137fb..65e1fd4 100644
--- a/source/blender/pointcache/alembic/abc_group.cpp
+++ b/source/blender/pointcache/alembic/abc_group.cpp
@@ -28,6 +28,7 @@
 #include "abc_object.h"
 
 extern "C" {
+#include "BLI_listbase.h"
 #include "BLI_math.h"
 
 #include "DNA_group_types.h"
@@ -136,8 +137,13 @@ void AbcDupligroupWriter::write_sample_object(Object *ob)
 	AbcWriter *ob_writer = find_id_writer((ID *)ob);
 	if (!ob_writer) {
 		bool do_mesh = do_cache_type(m_cachelib, ob, CACHE_TYPE_DERIVED_MESH);
-//		bool do_hair = do_cache_type(m_cachelib, ob, CACHE_TYPE_HAIR, ); // TODO
+		/* XXX TODO currently we cache all hair if any of them is enabled,
+		 * need to decide if individual particle system caching is needed at all
+		 */
 		bool do_hair = false;
+		int totpsys = BLI_listbase_count(&ob->particlesystem);
+		for (int i = 0; i < totpsys; ++i)
+			do_hair |= do_cache_type(m_cachelib, ob, CACHE_TYPE_HAIR, i);
 		
 		ob_writer = new AbcObjectWriter(ob->id.name, m_scene, ob, do_mesh, do_hair);
 		ob_writer->init(abc_archive());
diff --git a/source/blender/pointcache/alembic/abc_object.cpp b/source/blender/pointcache/alembic/abc_object.cpp
index 1332f83..72a8dc3 100644
--- a/source/blender/pointcache/alembic/abc_object.cpp
+++ b/source/blender/pointcache/alembic/abc_object.cpp
@@ -18,6 +18,7 @@
 
 #include "abc_mesh.h"
 #include "abc_object.h"
+#include "abc_particles.h"
 
 extern "C" {
 #include "BLI_math.h"
@@ -43,12 +44,23 @@ AbcObjectWriter::AbcObjectWriter(const std::string &name, Scene *scene, Object *
 			m_dm_writer = new AbcDerivedMeshWriter("mesh", ob, &m_final_dm);
 		}
 	}
+	
+	if (do_hair) {
+		for (ParticleSystem *psys = (ParticleSystem *)ob->particlesystem.first; psys; psys = psys->next) {
+			if (psys->part && psys->part->type == PART_HAIR) {
+				m_hair_writers.push_back(new AbcHairWriter(psys->name, ob, psys));
+			}
+		}
+	}
 }
 
 AbcObjectWriter::~AbcObjectWriter()
 {
 	if (m_dm_writer)
 		delete m_dm_writer;
+	for (int i = 0; i < m_hair_writers.size(); ++i)
+		if (m_hair_writers[i])
+			delete m_hair_writers[i];
 }
 
 void AbcObjectWriter::init_abc()
@@ -63,6 +75,14 @@ void AbcObjectWriter::init_abc()
 		m_dm_writer->init(abc_archive());
 		m_dm_writer->init_abc(m_abc_object);
 	}
+	
+	for (int i = 0; i < m_hair_writers.size(); ++i) {
+		AbcHairWriter *hair_writer = m_hair_writers[i];
+		if (hair_writer) {
+			hair_writer->init(abc_archive());
+			hair_writer->init_abc(m_abc_object);
+		}
+	}
 }
 
 #if 0
@@ -101,6 +121,13 @@ void AbcObjectWriter::write_sample()
 			}
 		}
 	}
+	
+	for (int i = 0; i < m_hair_writers.size(); ++i) {
+		AbcHairWriter *hair_writer = m_hair_writers[i];
+		if (hair_writer) {
+			hair_writer->write_sample();
+		}
+	}
 }
 
 
diff --git a/source/blender/pointcache/alembic/abc_object.h b/source/blender/pointcache/alembic/abc_object.h
index b3ae34a..fcd30d5 100644
--- a/source/blender/pointcache/alembic/abc_object.h
+++ b/source/blender/pointcache/alembic/abc_object.h
@@ -19,6 +19,8 @@
 #ifndef PTC_ABC_OBJECT_H
 #define PTC_ABC_OBJECT_H
 
+#include <vector>
+
 #include <Alembic/Abc/IObject.h>
 #include <Alembic/Abc/OObject.h>
 #include <Alembic/AbcGeom/IXform.h>
@@ -37,9 +39,12 @@ struct Scene;
 namespace PTC {
 
 class AbcDerivedMeshWriter;
+class AbcHairWriter;
 
 class AbcObjectWriter : public ObjectWriter, public AbcWriter {
 public:
+	typedef std::vector<AbcHairWriter *> HairWriters;
+	
 	AbcObjectWriter(const std::string &name, Scene *scene, Object *ob, bool do_mesh, bool do_hair);
 	~AbcObjectWriter();
 	
@@ -56,6 +61,7 @@ private:
 	
 	Abc::OObject m_abc_object;
 	AbcDerivedMeshWriter *m_dm_writer;
+	HairWriters m_hair_writers;
 };
 
 class AbcObjectReader : public ObjectReader, public AbcReader {
diff --git a/source/blender/pointcache/alembic/abc_particles.cpp b/source/blender/pointcache/alembic/abc_particles.cpp
index b9a9e0c..b89e437 100644
--- a/source/blender/pointcache/alembic/abc_particles.cpp
+++ b/source/blender/pointcache/alembic/abc_particles.cpp
@@ -128,6 +128,106 @@ PTCReadSampleResult AbcParticlesReader::read_sample(float frame)
 }
 
 
+struct ParticleHairSample {
+	std::vector<int32_t> numverts;
+	
+	std::vector<V3f> positions;
+	std::vector<float32_t> times;
+	std::vector<float32_t> weights;
+};
+
+AbcHairWriter::AbcHairWriter(const std::string &name, Object *ob, ParticleSystem *psys) :
+    ParticlesWriter(ob, psys, name)
+{
+}
+
+AbcHairWriter::~AbcHairWriter()
+{
+}
+
+void AbcHairWriter::init_abc(OObject parent)
+{
+	if (m_curves)
+		return;
+	m_curves = OCurves(parent, m_name, abc_archive()->frame_sampling_index());
+	
+	OCurvesSchema &schema = m_curves.getSchema();
+	OCompoundProperty geom_props = schema.getArbGeomParams();
+	
+	m_param_times = OFloatGeomParam(geom_props, "times", false, kVertexScope, 1, 0);
+	m_param_weights = OFloatGeomParam(geom_props, "weights", false, kVertexScope, 1, 0);
+}
+
+static int hair_count_totverts(ParticleSystem *psys)
+{
+	int p;
+	int totverts = 0;
+	
+	for (p = 0; p < psys->totpart; ++p) {
+		ParticleData *pa = &psys->particles[p];
+		totverts += pa->totkey;
+	}
+	
+	return totverts;
+}
+
+static void hair_create_sample(ParticleSystem *psys, ParticleHairSample &sample, bool do_numverts)
+{
+	int totpart = psys->totpart;
+	int totverts = hair_count_totverts(psys);
+	int p, k;
+	
+	if (totverts == 0)
+		return;
+	
+	if (do_numverts)
+		sample.numverts.reserve(totpart);
+	sample.positions.reserve(totverts);
+	sample.times.reserve(totverts);
+	sample.weights.reserve(totverts);
+	
+	for (p = 0; p < totpart; ++p) {
+		ParticleData *pa = &psys->particles[p];
+		int numverts = pa->totkey;
+		
+		if (do_numverts)
+			sample.numverts.push_back(numverts);
+		
+		for (k = 0; k < numverts; ++k) {
+			HairKey *key = &pa->hair[k];
+			
+			sample.positions.push_back(V3f(key->co[0], key->co[1], key->co[2]));
+			sample.times.push_back(key->time);
+			sample.weights.push_back(key->weight);
+		}
+	}
+}
+
+void AbcHairWriter::write_sample()
+{
+	if (!m_curves)
+		return;
+	
+	OCurvesSchema &schema = m_curves.getSchema();
+	
+	ParticleHairSample hair_sample;
+	OCurvesSchema::Sample sample;
+	if (schema.getNumSamples() == 0) {
+		/* write curve sizes only first time, assuming they are constant! */
+		hair_create_sample(m_psys, hair_sample, true);
+		sample = OCurvesSchema::Sample(hair_sample.positions, hair_sample.numverts);
+	}
+	else {
+		hair_create_sample(m_psys, hair_sample, false);
+		sample = OCurvesSchema::Sample(hair_sample.positions);
+	}
+	schema.set(sample);
+	
+	m_param_times.set(OFloatGeomParam::Sample(FloatArraySample(hair_sample.times), kVertexScope));
+	m_param_weights.set(OFloatGeomParam::Sample(FloatArraySample(hair_sample.weights), kVertexScope));
+}
+
+
 AbcHairDynamicsWriter::AbcHairDynamicsWriter(const std::string &name, Object *ob, ParticleSystem *psys) :
     ParticlesWriter(ob, psys, name),
     m_cloth_writer(name+"__cloth", ob, psys->clmd)
@@ -265,6 +365,7 @@ void AbcParticlePathcacheWriter::write_sample()
 		sample = OCurvesSchema::Sample(path_sample.positions, path_sample.numkeys);
 	}
 	else {
+		paths_create_sample(*m_pathcache, *m_totpath, totkeys, path_sample, false);
 		sample = OCurvesSchema::Sample(path_sample.positions);
 	}
 	schema.set(sample);
diff --git a/source/blender/pointcache/alembic/abc_particles.h b/source/blender/pointcache/alembic/abc_particles.h
index d9047be..9d0a23d 100644
--- a/source/blender/pointcache/alembic/abc_particles.h
+++ b/source/blender/pointcache/alembic/abc_particles.h
@@ -31,6 +31,7 @@
 #include "abc_reader.h"
 #include "abc_schema.h"
 #include "abc_writer.h"
+#include "abc_cloth.h"
 
 struct Object;
 struct ParticleSystem;
@@ -38,8 +39,6 @@ struct ParticleCacheKey;
 
 namespace PTC {
 
-class AbcClothWriter;
-class AbcClothReader;
 class AbcDerivedMeshWriter;
 class AbcDerivedMeshReader;
 
@@ -69,6 +68,22 @@ private:
 	AbcGeom::IPoints m_points;
 };
 
+class AbcHairWriter : public ParticlesWriter, public AbcWriter {
+public:
+	AbcHairWriter(const std::string &name, Object *ob, ParticleSystem *psys);
+	~AbcHairWriter();
+	
+	void init_abc(Abc::OObject parent);
+	
+	void write_sample();
+	
+private:
+	AbcGeom::OCurves m_curves;
+	
+	AbcGeom::OFloatGeomParam m_param_times;
+	AbcGeom::OFloatGeomParam m_param_weights;
+};
+
 
 /* Hair is just a cloth sim in disguise ... */




More information about the Bf-blender-cvs mailing list