[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