[Bf-blender-cvs] [c438f0e643b] temp-sybren-alembic-customprops-read: Added support for array properties with more than 1 element.

Sybren A. Stüvel noreply at git.blender.org
Thu Dec 7 10:36:31 CET 2017


Commit: c438f0e643b848f0c1399b0382dcf2db84cbed69
Author: Sybren A. Stüvel
Date:   Mon Nov 13 13:59:19 2017 +0100
Branches: temp-sybren-alembic-customprops-read
https://developer.blender.org/rBc438f0e643b848f0c1399b0382dcf2db84cbed69

Added support for array properties with more than 1 element.

Scalar-like arrays are still read as scalars.

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

M	source/blender/alembic/intern/abc_object.cc
M	source/blender/alembic/intern/abc_object.h

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

diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc
index 88f5f24cd1a..e4ccb03c3bc 100644
--- a/source/blender/alembic/intern/abc_object.cc
+++ b/source/blender/alembic/intern/abc_object.cc
@@ -375,10 +375,64 @@ void AbcObjectReader::decref()
 	BLI_assert(m_refcount >= 0);
 }
 
+/* 'sl' means 'scalar like', a concept of Alembic properties indicating single-valued arrays. */
+template<typename ABCTYPE>
+static IDProperty *read_array_sl_int(const PropertyHeader &header,
+                                     ArraySamplePtr val)
+{
+	const ABCTYPE *data = static_cast<const ABCTYPE *>(val->getData());
+	IDPropertyTemplate idval = { 0 };
+	idval.i = data[0];
+	return IDP_New(IDP_INT, &idval, header.getName().c_str());
+}
+
+template<typename ABCTYPE>
+static IDProperty *read_array_sl_float(const PropertyHeader &header,
+                                       ArraySamplePtr val)
+{
+	const ABCTYPE *data = static_cast<const ABCTYPE *>(val->getData());
+	IDPropertyTemplate idval = { 0 };
+	idval.f = data[0];
+	return IDP_New(IDP_FLOAT, &idval, header.getName().c_str());
+}
+
+template<typename ABCTYPE, typename BLTYPE>
+static IDProperty *read_array(char idp_type,
+                              const PropertyHeader &header,
+                              Alembic::Util::Dimensions dim,
+                              ArraySamplePtr val)
+{
+	const ABCTYPE *data = static_cast<const ABCTYPE *>(val->getData());
+
+	IDPropertyTemplate idval = { 0 };
+	idval.array.len = dim.numPoints();
+	idval.array.type = idp_type;
+	IDProperty *iddata = IDP_New(IDP_ARRAY, &idval, header.getName().c_str());
+
+	BLTYPE *array = (BLTYPE *)IDP_Array(iddata);
+	memcpy(array, data, dim.numPoints() * sizeof(BLTYPE));
+
+	return iddata;
+}
+
+template<typename ABCPROPTYPE>
+static IDProperty *read_scalar_int(ICompoundProperty params,
+                                   const PropertyHeader &header,
+                                   const Alembic::Abc::ISampleSelector &sample_sel)
+{
+	ABCPROPTYPE abcprop(params, header.getName());
+	IDPropertyTemplate idval = { 0 };
+	idval.i = abcprop.getValue(sample_sel);
+	return IDP_New(IDP_INT, &idval, header.getName().c_str());
+}
+
 void AbcObjectReader::read_custom_properties_into(ID *id,
                                                   ICompoundProperty params,
                                                   const Alembic::Abc::ISampleSelector &sample_sel)
 {
+	/* For all the Alembic data types like uint8_t. */
+	using namespace Alembic::Util;
+
 	/* This makes it easier for our callers to just pass ob->data without checking. */
 	if (id == NULL) return;
 
@@ -387,115 +441,116 @@ void AbcObjectReader::read_custom_properties_into(ID *id,
 		return;
 	}
 
-	IDPropertyTemplate idval = { 0 };
-	char idproptype;
-
 	size_t pcount = params.getNumProperties();
 	std::cerr << "Found " << pcount << " properties on " << params.getName() << "\n";
+	const bool import_scalarlike_as_scalar = true;
 	for (size_t pidx=0; pidx < pcount; pidx++) {
 		PropertyHeader header = params.getPropertyHeader(pidx);
 		std::cerr << "Found property: " << header.getName() << "\n";
 
-		/* The code below this point MUST set idproptype and idval correctly
-		 * for the current Alembic property, or use 'continue' to skip it. */
+		/* The code below this point MUST set iddata or use 'continue' to skip this prop. */
+		IDProperty *iddata = NULL;
 
 		if (header.isCompound()) {
 			std::cerr << "Custom property " << header.getName() << " is compound, not supported yet.\n";
 			continue;
 		}
 		if (header.isArray()) {
-			Alembic::AbcGeom::IArrayProperty ap(params, header.getName());
-			if (!ap.isScalarLike()) {
-				Alembic::Util::Dimensions dim;
-				ap.getDimensions(dim, sample_sel);
-				std::cerr << "Custom property " << header.getName() << " is array of " << dim << " items, not supported yet.\n";
-				continue;
-			}
-			std::cerr << "    - array is constant: " << ap.isConstant() << "\n";
+			std::cerr << "    - POD: " << header.getDataType().getPod() << "\n";
+			IArrayProperty ap(params, header.getName());
 
 			ArraySamplePtr val;
 			ap.get(val, sample_sel);
+			std::cerr << "    - array is constant: " << ap.isConstant() << "\n";
 
-			/* Inspired by ArrayPropertiesTests.cpp in the Alembic source code. */
-			switch (header.getDataType().getPod()) {
-				case Alembic::Util::kBooleanPOD:
-				{
-					Alembic::Util::bool_t *data = (Alembic::Util::bool_t *)(val->getData());
-					idval.i = data[0];
-					idproptype = IDP_INT;
-					break;
-				}
-				case Alembic::Util::kUint8POD:
-				{
-					Alembic::Util::uint8_t *data = (Alembic::Util::uint8_t *)(val->getData());
-					idval.i = data[0];
-					idproptype = IDP_INT;
-					break;
-				}
-				case Alembic::Util::kInt8POD:
-				{
-					Alembic::Util::int8_t *data = (Alembic::Util::int8_t *)(val->getData());
-					idval.i = data[0];
-					idproptype = IDP_INT;
-					break;
-				}
-				case Alembic::Util::kUint16POD:
-				{
-					Alembic::Util::uint16_t *data = (Alembic::Util::uint16_t *)(val->getData());
-					idval.i = data[0];
-					idproptype = IDP_INT;
-					break;
-				}
-				case Alembic::Util::kInt16POD:
-				{
-					Alembic::Util::int16_t *data = (Alembic::Util::int16_t *)(val->getData());
-					idval.i = data[0];
-					idproptype = IDP_INT;
-					break;
+			Dimensions dim;
+			ap.getDimensions(dim, sample_sel);
+
+			if (ap.isScalarLike() && import_scalarlike_as_scalar) {
+				/* Inspired by ArrayPropertyTests.cpp in the Alembic source code. */
+				switch (header.getDataType().getPod()) {
+					case kBooleanPOD:
+						iddata = read_array_sl_int<bool_t>(header, val);
+						break;
+					case kUint8POD:
+						iddata = read_array_sl_int<uint8_t>(header, val);
+						break;
+					case kInt8POD:
+						iddata = read_array_sl_int<int8_t>(header, val);
+						break;
+					case kUint16POD:
+						iddata = read_array_sl_int<uint16_t>(header, val);
+						break;
+					case kInt16POD:
+						iddata = read_array_sl_int<int16_t>(header, val);
+						break;
+					case kUint32POD:
+						iddata = read_array_sl_int<uint32_t>(header, val);
+						break;
+					case kInt32POD:
+						iddata = read_array_sl_int<int32_t>(header, val);
+						break;
+					case kFloat16POD:
+						iddata = read_array_sl_float<float16_t>(header, val);
+						break;
+					case kFloat32POD:
+						iddata = read_array_sl_float<float32_t>(header, val);
+						break;
+					case kStringPOD:
+					{
+						string * data = (string *)(val->getData());
+						IDPropertyTemplate idval = { 0 };
+						idval.string.str = data->c_str();
+						idval.string.len = data->size() + 1;
+						idval.string.subtype = IDP_STRING_SUB_UTF8; // big fat assumption the world is sane.
+						iddata = IDP_New(IDP_STRING, &idval, header.getName().c_str());
+						break;
+					}
+					default:
+						std::cerr << "Custom property " << header.getName() << " is array of data type " << header.getDataType() << "; not supported.\n";
+						continue;
 				}
-				case Alembic::Util::kUint32POD:
-				{
-					Alembic::Util::uint32_t *data = (Alembic::Util::uint32_t *)(val->getData());
-					idval.i = data[0];
-					idproptype = IDP_INT;
-					break;
-				}
-				case Alembic::Util::kInt32POD:
-				{
-					Alembic::Util::int32_t *data = (Alembic::Util::int32_t *)(val->getData());
-					idval.i = data[0];
-					idproptype = IDP_INT;
-					break;
-				}
-//				case Alembic::Util::kUint64POD: break;
-//				case Alembic::Util::kInt64POD: break;
-				case Alembic::Util::kFloat16POD:
-				{
-					Alembic::Util::float16_t *data = (Alembic::Util::float16_t *)(val->getData());
-					idval.f = data[0];
-					idproptype = IDP_FLOAT;
-					break;
-				}
-				case Alembic::Util::kFloat32POD:
-				{
-					Alembic::Util::float32_t *data = (Alembic::Util::float32_t *)(val->getData());
-					idval.f = data[0];
-					idproptype = IDP_FLOAT;
-					break;
-				}
-//				case Alembic::Util::kFloat64POD: break;
-				case Alembic::Util::kStringPOD:
-				{
-					Alembic::Util::string * data = (Alembic::Util::string *)(val->getData());
-					idval.string.str = data->c_str();
-					idval.string.len = data->size() + 1;
-					idval.string.subtype = IDP_STRING_SUB_UTF8; // big fat assumption the world is sane.
-					idproptype = IDP_STRING;
-					break;
+			}
+			else {
+				/* Inspired by ArrayPropertyTests.cpp in the Alembic source code. */
+				switch (header.getDataType().getPod()) {
+					case kBooleanPOD:
+						iddata = read_array<bool_t, int>(IDP_INT, header, dim, val);
+						break;
+					case kUint8POD:
+						iddata = read_array<uint8_t, int>(IDP_INT, header, dim, val);
+						break;
+					case kInt8POD:
+						iddata = read_array<int8_t, int>(IDP_INT, header, dim, val);
+						break;
+					case kUint16POD:
+						iddata = read_array<uint16_t, int>(IDP_INT, header, dim, val);
+						break;
+					case kInt16POD:
+						iddata = read_array<int16_t, int>(IDP_INT, header, dim, val);
+						break;
+					case kUint32POD:
+						iddata = read_array<uint32_t, int>(IDP_INT, header, dim, val);
+						break;
+					case kInt32POD:
+						iddata = read_array<int32_t, int>(IDP_INT, header, dim, val);
+						break;
+					case kFloat16POD:
+						iddata = read_array<float16_t, float>(IDP_FLOAT, header, dim, val);
+						break;
+					case kFloat32POD:
+						iddata = read_array<float32_t, float>(IDP_FLOAT, header, dim, val);
+						break;
+					default:
+						/* TODO(Sybren): use the ABC_xxx logging system so this results
+						 * in a warning in the UI. Same for similar default cases. */
+						std::cerr << "Custom property " << header.getName()
+						          << " is array of data type " << header.getDataType()
+						          << " and dimensions " << dim
+						          << "; not supported."
+						          << std::endl;
+						continue;
 				}
-				default:
-					std::cerr << "Custom property " << header.getName() << " is array of data type " << header.getDataType() << "; not supported.\n";
-					continue;
 			}
 		}
 		else {
@@ -503,84 +558,59 @@ void AbcObjectReader::read_custom_properties_into(ID *id,
 			BLI_assert(header.isScalar());
 
 			switch (header.getDataType().getPod()) {
-				case Alembic::Util::kBooleanPOD:
-				{
-					IBoolProperty abcprop

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list