[Bf-blender-cvs] [753edaf] master: Alembic: store a pointer to the object reader in the cache modifiers and constraints.

Kévin Dietrich noreply at git.blender.org
Sat Oct 29 12:25:13 CEST 2016


Commit: 753edafcb77d9aaf07fe869372319b841dd80681
Author: Kévin Dietrich
Date:   Sat Oct 29 12:23:09 2016 +0200
Branches: master
https://developer.blender.org/rB753edafcb77d9aaf07fe869372319b841dd80681

Alembic: store a pointer to the object reader in the cache modifiers and
constraints.

This avoids traversing the archive everytime object data is needed and
gives an overall consistent ~2x speedup here with files containing
between 136 and 500 Alembic objects. Also this somewhat nicely de-
duplicates code between data creation (upon import) and data streaming
(modifiers and constraints).

The only worying part is what happens when a CacheFile is deleted and/or
has its path changed. For now, we traverse the whole scene and for each
object using the CacheFile we free the pointer and NULL-ify it (see
BKE_cachefile_clean), but at some point this should be re-considered and
make use of the dependency graph.

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

M	source/blender/alembic/ABC_alembic.h
M	source/blender/alembic/intern/abc_curves.cc
M	source/blender/alembic/intern/abc_curves.h
M	source/blender/alembic/intern/abc_mesh.cc
M	source/blender/alembic/intern/abc_mesh.h
M	source/blender/alembic/intern/abc_object.cc
M	source/blender/alembic/intern/abc_object.h
M	source/blender/alembic/intern/abc_points.cc
M	source/blender/alembic/intern/abc_points.h
M	source/blender/alembic/intern/abc_util.cc
M	source/blender/alembic/intern/abc_util.h
M	source/blender/alembic/intern/alembic_capi.cc
M	source/blender/blenkernel/BKE_cachefile.h
M	source/blender/blenkernel/intern/cachefile.c
M	source/blender/blenkernel/intern/constraint.c
M	source/blender/makesdna/DNA_cachefile_types.h
M	source/blender/makesdna/DNA_constraint_types.h
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_cachefile.c
M	source/blender/makesrna/intern/rna_constraint.c
M	source/blender/makesrna/intern/rna_modifier.c
M	source/blender/modifiers/intern/MOD_meshsequencecache.c

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

diff --git a/source/blender/alembic/ABC_alembic.h b/source/blender/alembic/ABC_alembic.h
index e62713f..e92d5f2 100644
--- a/source/blender/alembic/ABC_alembic.h
+++ b/source/blender/alembic/ABC_alembic.h
@@ -28,6 +28,7 @@ extern "C" {
 #endif
 
 struct bContext;
+struct CacheReader;
 struct DerivedMesh;
 struct ListBase;
 struct Object;
@@ -92,21 +93,25 @@ AbcArchiveHandle *ABC_create_handle(const char *filename, struct ListBase *objec
 
 void ABC_free_handle(AbcArchiveHandle *handle);
 
-void ABC_get_transform(AbcArchiveHandle *handle,
-                       struct Object *ob,
-                       const char *object_path,
+void ABC_get_transform(struct CacheReader *reader,
                        float r_mat[4][4],
                        float time,
                        float scale);
 
-struct DerivedMesh *ABC_read_mesh(AbcArchiveHandle *handle,
+struct DerivedMesh *ABC_read_mesh(struct CacheReader *reader,
                                   struct Object *ob,
                                   struct DerivedMesh *dm,
-                                  const char *object_path,
                                   const float time,
                                   const char **err_str,
                                   int flags);
 
+void CacheReader_free(struct CacheReader *reader);
+
+struct CacheReader *CacheReader_open_alembic_object(struct AbcArchiveHandle *handle,
+                                                    struct CacheReader *reader,
+                                                    struct Object *object,
+                                                    const char *object_path);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/source/blender/alembic/intern/abc_curves.cc b/source/blender/alembic/intern/abc_curves.cc
index 2b54741..7e5ea3b 100644
--- a/source/blender/alembic/intern/abc_curves.cc
+++ b/source/blender/alembic/intern/abc_curves.cc
@@ -37,6 +37,7 @@ extern "C" {
 
 #include "BLI_listbase.h"
 
+#include "BKE_cdderivedmesh.h"
 #include "BKE_curve.h"
 #include "BKE_object.h"
 
@@ -353,3 +354,54 @@ void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const float time)
 		BLI_addtail(BKE_curve_nurbs_get(cu), nu);
 	}
 }
+
+/* NOTE: Alembic only stores data about control points, but the DerivedMesh
+ * passed from the cache modifier contains the displist, which has more data
+ * than the control points, so to avoid corrupting the displist we modify the
+ * object directly and create a new DerivedMesh from that. Also we might need to
+ * create new or delete existing NURBS in the curve.
+ */
+DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh */*dm*/, const float time, int /*read_flag*/)
+{
+	ISampleSelector sample_sel(time);
+	const ICurvesSchema::Sample sample = m_curves_schema.getValue(sample_sel);
+
+	const P3fArraySamplePtr &positions = sample.getPositions();
+	const Int32ArraySamplePtr num_vertices = sample.getCurvesNumVertices();
+
+	int vertex_idx = 0;
+	int curve_idx = 0;
+	Curve *curve = static_cast<Curve *>(m_object->data);
+
+	const int curve_count = BLI_listbase_count(&curve->nurb);
+
+	if (curve_count != num_vertices->size()) {
+		BKE_nurbList_free(&curve->nurb);
+		read_curve_sample(curve, m_curves_schema, time);
+	}
+	else {
+		Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
+		for (; nurbs; nurbs = nurbs->next, ++curve_idx) {
+			const int totpoint = (*num_vertices)[curve_idx];
+
+			if (nurbs->bp) {
+				BPoint *point = nurbs->bp;
+
+				for (int i = 0; i < totpoint; ++i, ++point, ++vertex_idx) {
+					const Imath::V3f &pos = (*positions)[vertex_idx];
+					copy_yup_zup(point->vec, pos.getValue());
+				}
+			}
+			else if (nurbs->bezt) {
+				BezTriple *bezier = nurbs->bezt;
+
+				for (int i = 0; i < totpoint; ++i, ++bezier, ++vertex_idx) {
+					const Imath::V3f &pos = (*positions)[vertex_idx];
+					copy_yup_zup(bezier->vec[1], pos.getValue());
+				}
+			}
+		}
+	}
+
+	return CDDM_from_curve(m_object);
+}
diff --git a/source/blender/alembic/intern/abc_curves.h b/source/blender/alembic/intern/abc_curves.h
index ee47f19..979ee8a 100644
--- a/source/blender/alembic/intern/abc_curves.h
+++ b/source/blender/alembic/intern/abc_curves.h
@@ -56,10 +56,11 @@ public:
 	bool valid() const;
 
 	void readObjectData(Main *bmain, float time);
+	DerivedMesh *read_derivedmesh(DerivedMesh *, const float time, int);
 };
 
 /* ************************************************************************** */
 
 void read_curve_sample(Curve *cu, const Alembic::AbcGeom::ICurvesSchema &schema, const float time);
 
-#endif  /* __ABC_CURVES_H__ */
\ No newline at end of file
+#endif  /* __ABC_CURVES_H__ */
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index bb5d5ce..5b282e3 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -646,75 +646,6 @@ void AbcMeshWriter::getGeoGroups(
 /* Some helpers for mesh generation */
 namespace utils {
 
-void mesh_add_verts(Mesh *mesh, size_t len)
-{
-	if (len == 0) {
-		return;
-	}
-
-	const int totvert = mesh->totvert + len;
-	CustomData vdata;
-	CustomData_copy(&mesh->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
-	CustomData_copy_data(&mesh->vdata, &vdata, 0, 0, mesh->totvert);
-
-	if (!CustomData_has_layer(&vdata, CD_MVERT)) {
-		CustomData_add_layer(&vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
-	}
-
-	CustomData_free(&mesh->vdata, mesh->totvert);
-	mesh->vdata = vdata;
-	BKE_mesh_update_customdata_pointers(mesh, false);
-
-	mesh->totvert = totvert;
-}
-
-static void mesh_add_mloops(Mesh *mesh, size_t len)
-{
-	if (len == 0) {
-		return;
-	}
-
-	/* new face count */
-	const int totloops = mesh->totloop + len;
-
-	CustomData ldata;
-	CustomData_copy(&mesh->ldata, &ldata, CD_MASK_MESH, CD_DEFAULT, totloops);
-	CustomData_copy_data(&mesh->ldata, &ldata, 0, 0, mesh->totloop);
-
-	if (!CustomData_has_layer(&ldata, CD_MLOOP)) {
-		CustomData_add_layer(&ldata, CD_MLOOP, CD_CALLOC, NULL, totloops);
-	}
-
-	CustomData_free(&mesh->ldata, mesh->totloop);
-	mesh->ldata = ldata;
-	BKE_mesh_update_customdata_pointers(mesh, false);
-
-	mesh->totloop = totloops;
-}
-
-static void mesh_add_mpolygons(Mesh *mesh, size_t len)
-{
-	if (len == 0) {
-		return;
-	}
-
-	const int totpolys = mesh->totpoly + len;
-
-	CustomData pdata;
-	CustomData_copy(&mesh->pdata, &pdata, CD_MASK_MESH, CD_DEFAULT, totpolys);
-	CustomData_copy_data(&mesh->pdata, &pdata, 0, 0, mesh->totpoly);
-
-	if (!CustomData_has_layer(&pdata, CD_MPOLY)) {
-		CustomData_add_layer(&pdata, CD_MPOLY, CD_CALLOC, NULL, totpolys);
-	}
-
-	CustomData_free(&mesh->pdata, mesh->totpoly);
-	mesh->pdata = pdata;
-	BKE_mesh_update_customdata_pointers(mesh, false);
-
-	mesh->totpoly = totpolys;
-}
-
 static void build_mat_map(const Main *bmain, std::map<std::string, Material *> &mat_map)
 {
 	Material *material = static_cast<Material *>(bmain->mat.first);
@@ -786,45 +717,6 @@ struct AbcMeshData {
 	UInt32ArraySamplePtr uvs_indices;
 };
 
-static void *add_customdata_cb(void *user_data, const char *name, int data_type)
-{
-	Mesh *mesh = static_cast<Mesh *>(user_data);
-	CustomDataType cd_data_type = static_cast<CustomDataType>(data_type);
-	void *cd_ptr = NULL;
-
-	int index = -1;
-	if (cd_data_type == CD_MLOOPUV) {
-		index = ED_mesh_uv_texture_add(mesh, name, true);
-		cd_ptr = CustomData_get_layer(&mesh->ldata, cd_data_type);
-	}
-	else if (cd_data_type == CD_MLOOPCOL) {
-		index = ED_mesh_color_add(mesh, name, true);
-		cd_ptr = CustomData_get_layer(&mesh->ldata, cd_data_type);
-	}
-
-	if (index == -1) {
-		return NULL;
-	}
-
-	return cd_ptr;
-}
-
-CDStreamConfig create_config(Mesh *mesh)
-{
-	CDStreamConfig config;
-
-	config.mvert = mesh->mvert;
-	config.mpoly = mesh->mpoly;
-	config.mloop = mesh->mloop;
-	config.totpoly = mesh->totpoly;
-	config.totloop = mesh->totloop;
-	config.user_data = mesh;
-	config.loopdata = &mesh->ldata;
-	config.add_customdata_cb = add_customdata_cb;
-
-	return config;
-}
-
 static void read_mverts_interp(MVert *mverts, const P3fArraySamplePtr &positions, const P3fArraySamplePtr &ceil_positions, const float weight)
 {
 	float tmp[3];
@@ -1002,23 +894,15 @@ void AbcMeshReader::readObjectData(Main *bmain, float time)
 	m_object->data = mesh;
 
 	const ISampleSelector sample_sel(time);
-	const IPolyMeshSchema::Sample sample = m_schema.getValue(sample_sel);
-
-	const P3fArraySamplePtr &positions = sample.getPositions();
-	const Int32ArraySamplePtr &face_indices = sample.getFaceIndices();
-    const Int32ArraySamplePtr &face_counts = sample.getFaceCounts();
-
-	utils::mesh_add_verts(mesh, positions->size());
-	utils::mesh_add_mpolygons(mesh, face_counts->size());
-	utils::mesh_add_mloops(mesh, face_indices->size());
 
-	m_mesh_data = create_config(mesh);
+	DerivedMesh *dm = CDDM_from_mesh(mesh);
+	DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL);
 
-	bool has_smooth_normals = false;
-	read_mesh_sample(m_settings, m_schema, sample_sel, m_mesh_data, has_smooth_normals);
+	if (ndm != dm) {
+		dm->release(dm);
+	}
 
-	BKE_mesh_calc_normals(mesh);
-	BKE_mesh_calc_edges(mesh, false, false);
+	DM_to_mesh(ndm, mesh, m_object, CD_MASK_MESH, true);
 
 	if (m_settings->validate_meshes) {
 		BKE_mesh_validate(mesh, false, false);
@@ -1031,6 +915,120 @@ void AbcMeshReader::readObjectData(Main *bmain, float time)
 	}
 }
 
+static bool check_smooth_poly_flag(DerivedMesh *dm)
+{
+	MPoly *mpolys = dm->getPolyArray(dm);
+
+	for (int i = 0, e = dm->getNumPolys(dm); i < e; ++i) {
+		MPoly &poly = mpolys[i];
+
+		if ((poly.flag & ME_SMOOTH) != 0) {
+			return true;
+		}
+	}
+
+	return false;
+}
+
+static void set_smooth_poly_flag(DerivedMesh *dm)
+{
+	MPoly *mpolys = dm->getPolyArray(dm);
+
+	for (int i = 0, e = dm->getNumPolys(dm); i < e; ++i) {
+		MPoly &poly = mpolys[i];
+		poly.flag |= ME_SMOOTH;
+	}
+}
+
+static void *add_customdata_cb(void *user_data, const char *name, int data_type)
+{
+	DerivedMesh *dm = static_cast<DerivedMesh *>(user_data);
+	CustomDataType cd_data_type = static_cast<CustomDataType>(data_type);
+	void *cd_ptr = NULL;
+
+	if (ELEM(cd_data_type, CD_MLOOPUV, CD_MLOOPCOL)) {
+		cd_ptr = CustomData_get_layer_named(dm->getLoopDataLayout(dm), cd_data_type, name);
+
+	

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list