[Bf-blender-cvs] [bf047cb] gooseberry: Write basic hair curves to caches for dupli groups.

Lukas Tönne noreply at git.blender.org
Tue Mar 24 12:59:33 CET 2015


Commit: bf047cb850a4dff1ea93ccd3d41e31e84e5b12ed
Author: Lukas Tönne
Date:   Tue Mar 24 12:57:30 2015 +0100
Branches: gooseberry
https://developer.blender.org/rBbf047cb850a4dff1ea93ccd3d41e31e84e5b12ed

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