[Bf-blender-cvs] [d875c5a] alembic_basic_io: Refactor mesh reading code to de-duplicate logic with data streaming code.

Kévin Dietrich noreply at git.blender.org
Wed Jul 13 15:01:32 CEST 2016


Commit: d875c5adfbe088aa537890e726dd172925804018
Author: Kévin Dietrich
Date:   Wed Jul 13 11:04:20 2016 +0200
Branches: alembic_basic_io
https://developer.blender.org/rBd875c5adfbe088aa537890e726dd172925804018

Refactor mesh reading code to de-duplicate logic with data streaming
code.

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

M	source/blender/alembic/intern/abc_customdata.h
M	source/blender/alembic/intern/abc_mesh.cc
M	source/blender/alembic/intern/abc_mesh.h
M	source/blender/alembic/intern/alembic_capi.cc

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

diff --git a/source/blender/alembic/intern/abc_customdata.h b/source/blender/alembic/intern/abc_customdata.h
index a5eba88..b6aa7b6 100644
--- a/source/blender/alembic/intern/abc_customdata.h
+++ b/source/blender/alembic/intern/abc_customdata.h
@@ -28,7 +28,9 @@
 
 struct CustomData;
 struct MLoop;
+struct MLoopUV;
 struct MPoly;
+struct MVert;
 
 using Alembic::Abc::ICompoundProperty;
 using Alembic::Abc::OCompoundProperty;
@@ -45,8 +47,13 @@ struct CDStreamConfig {
 	MPoly *mpoly;
 	int totpoly;
 
+	MVert *mvert;
 	int totvert;
 
+	MLoopUV *mloopuv;
+
+	CustomData *loopdata;
+
 	bool pack_uvs;
 
 	/* TODO(kevin): might need a better way to handle adding and/or updating
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index 016cc31..e813f7f 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -781,270 +781,291 @@ static void assign_materials(Main *bmain, Object *ob, const std::map<std::string
 
 /* ************************************************************************** */
 
-template <typename Schema>
-static bool has_animations(Schema &schema, ImportSettings *settings)
-{
-	if (settings->is_sequence) {
-		return true;
-	}
+using Alembic::AbcGeom::UInt32ArraySamplePtr;
+using Alembic::AbcGeom::V2fArraySamplePtr;
 
-	if (!schema.isConstant()) {
-		return true;
-	}
+struct AbcMeshData {
+	Int32ArraySamplePtr face_indices;
+	Int32ArraySamplePtr face_counts;
 
-	const ICompoundProperty &arb_geom_params = schema.getArbGeomParams();
+	P3fArraySamplePtr positions;
 
-	if (!arb_geom_params.valid()) {
-		return false;
-	}
+	N3fArraySamplePtr vertex_normals;
+	N3fArraySamplePtr face_normals;
 
-	const size_t num_props = arb_geom_params.getNumProperties();
+	V2fArraySamplePtr uvs;
+	UInt32ArraySamplePtr uvs_indices;
+};
 
-	for (size_t i = 0; i < num_props; ++i) {
-		const Alembic::Abc::PropertyHeader &propHeader = arb_geom_params.getPropertyHeader(i);
+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;
 
-		/* Check for animated UVs. */
-		if (IV2fGeomParam::matches(propHeader) && Alembic::AbcGeom::isUV(propHeader)) {
-			IV2fGeomParam uv_geom_param(arb_geom_params, propHeader.getName());
+	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 (!uv_geom_param.isConstant()) {
-				return true;
-			}
-		}
+	if (index == -1) {
+		return NULL;
 	}
 
-	return false;
+	return cd_ptr;
 }
 
-AbcMeshReader::AbcMeshReader(const IObject &object, ImportSettings &settings, bool is_subd)
-    : AbcObjectReader(object, settings)
+ABC_INLINE CDStreamConfig create_config(Mesh *mesh)
 {
-	if (is_subd) {
-		ISubD isubd_mesh(m_iobject, kWrapExisting);
-		m_subd_schema = isubd_mesh.getSchema();
-		get_min_max_time(m_subd_schema, m_min_time, m_max_time);
-	}
-	else {
-		IPolyMesh ipoly_mesh(m_iobject, kWrapExisting);
-		m_schema = ipoly_mesh.getSchema();
-		get_min_max_time(m_schema, m_min_time, m_max_time);
-	}
+	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.add_customdata_cb = add_customdata_cb;
+
+	return config;
 }
 
-bool AbcMeshReader::valid() const
+static void read_mverts(CDStreamConfig &config, const AbcMeshData &mesh_data)
 {
-	return m_schema.valid() || m_subd_schema.valid();
+	MVert *mverts = config.mvert;
+	const P3fArraySamplePtr &positions = mesh_data.positions;
+	const N3fArraySamplePtr &normals = mesh_data.vertex_normals;
+
+	read_mverts(mverts, positions, normals);
 }
 
-static MEdge *find_edge(MEdge *edges, int totedge, int v1, int v2)
+void read_mverts(MVert *mverts, const P3fArraySamplePtr &positions, const N3fArraySamplePtr &normals)
 {
-	for (int i = 0, e = totedge; i < e; ++i) {
-		MEdge &edge = edges[i];
+	for (int i = 0; i < positions->size(); ++i) {
+		MVert &mvert = mverts[i];
+		Imath::V3f pos_in = (*positions)[i];
 
-		if (edge.v1 == v1 && edge.v2 == v2) {
-			return &edge;
+		copy_yup_zup(mvert.co, pos_in.getValue());
+
+		mvert.bweight = 0;
+
+		if (normals) {
+			Imath::V3f nor_in = (*normals)[i];
+
+			short no[3];
+			normal_float_to_short_v3(no, nor_in.getValue());
+
+			copy_yup_zup(mvert.no, no);
 		}
 	}
-
-	return NULL;
 }
 
-void AbcMeshReader::readObjectData(Main *bmain, Scene *scene, float time)
+static void read_mpolys(CDStreamConfig &config, const AbcMeshData &mesh_data)
 {
-	Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
+	MPoly *mpolys = config.mpoly;
+	MLoop *mloops = config.mloop;
+	MLoopUV *mloopuvs = config.mloopuv;
+	CustomData *ldata = config.loopdata;
 
-	const ISampleSelector sample_sel(time);
-	const size_t poly_start = mesh->totpoly;
+	const Int32ArraySamplePtr &face_indices = mesh_data.face_indices;
+	const Int32ArraySamplePtr &face_counts = mesh_data.face_counts;
+	const V2fArraySamplePtr &uvs = mesh_data.uvs;
+	const UInt32ArraySamplePtr &uvs_indices = mesh_data.uvs_indices;
+	const N3fArraySamplePtr &normals = mesh_data.face_normals;
 
-	bool is_constant = true;
+	float (*pnors)[3] = NULL;
 
-	if (m_subd_schema.valid()) {
-		is_constant = !has_animations(m_subd_schema, m_settings);
+	if (normals) {
+		void *vptr = CustomData_get_layer(ldata, CD_NORMAL);
 
-		const ISubDSchema::Sample sample = m_subd_schema.getValue(sample_sel);
+		if (!vptr) {
+			vptr = CustomData_add_layer(ldata, CD_NORMAL, CD_CALLOC, NULL, normals->size());
+		}
 
-		readVertexDataSample(mesh, sample.getPositions(), N3fArraySamplePtr());
-		readPolyDataSample(mesh, sample.getFaceIndices(), sample.getFaceCounts(), N3fArraySamplePtr());
+		pnors = static_cast<float (*)[3]>(vptr);
 	}
-	else {
-		is_constant = !has_animations(m_schema, m_settings);
 
-		const IPolyMeshSchema::Sample sample = m_schema.getValue(sample_sel);
+	const bool do_normals = (normals && pnors);
+	const bool do_uvs = (mloopuvs && uvs && uvs_indices) && (uvs_indices->size() == face_indices->size());
+	unsigned int loop_index = 0;
+	unsigned int rev_loop_index = 0;
+	unsigned int uv_index = 0;
+	Imath::V3f nor;
 
-		N3fArraySamplePtr vertex_normals, poly_normals;
-		const IN3fGeomParam normals = m_schema.getNormalsParam();
+	for (int i = 0; i < face_counts->size(); ++i) {
+		const int face_size = (*face_counts)[i];
 
-		if (normals.valid()) {
-			IN3fGeomParam::Sample normsamp = normals.getExpandedValue(sample_sel);
+		MPoly &poly = mpolys[i];
+		poly.loopstart = loop_index;
+		poly.totloop = face_size;
 
-			if (normals.getScope() == Alembic::AbcGeom::kFacevaryingScope) {
-				poly_normals = normsamp.getVals();
-			}
-			else if ((normals.getScope() == Alembic::AbcGeom::kVertexScope) ||
-			         (normals.getScope() == Alembic::AbcGeom::kVaryingScope))
-			{
-				vertex_normals = normsamp.getVals();
+		/* NOTE: Alembic data is stored in the reverse order. */
+		rev_loop_index = loop_index + (face_size - 1);
+
+		for (int f = 0; f < face_size; ++f, ++loop_index, --rev_loop_index) {
+			MLoop &loop = mloops[rev_loop_index];
+			loop.v = (*face_indices)[loop_index];
+
+			if (do_normals) {
+				nor = (*normals)[loop_index];
+				copy_yup_zup(pnors[rev_loop_index], nor.getValue());
 			}
-		}
 
-		readVertexDataSample(mesh, sample.getPositions(), vertex_normals);
-		readPolyDataSample(mesh, sample.getFaceIndices(), sample.getFaceCounts(), poly_normals);
+			if (do_uvs) {
+				MLoopUV &loopuv = mloopuvs[rev_loop_index];
 
-		if (!vertex_normals && !poly_normals) {
-			BKE_mesh_calc_normals(mesh);
+				uv_index = (*uvs_indices)[loop_index];
+				loopuv.uv[0] = (*uvs)[uv_index][0];
+				loopuv.uv[1] = (*uvs)[uv_index][1];
+			}
 		}
 	}
+}
 
-	BKE_mesh_validate(mesh, false, false);
-
-	m_object = BKE_object_add(bmain, scene, OB_MESH, m_object_name.c_str());
-	m_object->data = mesh;
-
-	readFaceSetsSample(bmain, mesh, poly_start, sample_sel);
-
-	if (m_subd_schema.valid()) {
-		const ISubDSchema::Sample sample = m_subd_schema.getValue(sample_sel);
-
-		Int32ArraySamplePtr indices = sample.getCreaseIndices();
-		Alembic::Abc::FloatArraySamplePtr sharpnesses = sample.getCreaseSharpnesses();
+ABC_INLINE void read_uvs_params(CDStreamConfig &config,
+                                AbcMeshData &abc_data,
+                                const IV2fGeomParam &uv,
+                                const ISampleSelector &selector)
+{
+	if (!uv.valid()) {
+		return;
+	}
 
-		MEdge *edges = mesh->medge;
+	IV2fGeomParam::Sample uvsamp;
+	uv.getIndexed(uvsamp, selector);
 
-		if (indices && sharpnesses) {
-			for (int i = 0, s = 0, e = indices->size(); i < e; i += 2, ++s) {
-				MEdge *edge = find_edge(edges, mesh->totedge, (*indices)[i], (*indices)[i + 1]);
+	abc_data.uvs = uvsamp.getVals();
+	abc_data.uvs_indices = uvsamp.getIndices();
 
-				if (edge) {
-					edge->crease = FTOCHAR((*sharpnesses)[s]);
-				}
-			}
+	if (abc_data.uvs_indices->size() == config.totloop) {
+		std::string name = Alembic::Abc::GetSourceName(uv.getMetaData());
 
-			mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
+		/* According to the convention, primary UVs should have had their name
+		 * set using Alembic::Abc::SetSourceName, but you can't expect everyone
+		 * to follow it! :) */
+		if (name.empty()) {
+			name = uv.getName();
 		}
-	}
 
-	if (!is_constant) {
-		addDefaultModifier();
+		void *cd_ptr = config.add_customdata_cb(config.user_data, name.c_str(), CD_MLOOPUV);
+		config.mloopuv = static_cast<MLoopUV *>(cd_ptr);
 	}
 }
 
-void AbcMeshReader::readVertexDataSample(Mesh *mesh,
-                                         const P3fArraySamplePtr &positions,
-                                         const N3fArraySamplePtr &normals)
+ABC_INLINE void read_normals_params(AbcMeshData &abc_data,
+                                    const IN3fGeomParam normals,
+                                

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list