[Bf-blender-cvs] [fed050922a7] temp-sybren-alembic-customprops-read: Alembic: Added support for reading animated custom properties
Sybren A. Stüvel
noreply at git.blender.org
Thu Dec 7 10:36:35 CET 2017
Commit: fed050922a78d4779d128224f216c9e5ef040f71
Author: Sybren A. Stüvel
Date: Mon Nov 13 15:55:29 2017 +0100
Branches: temp-sybren-alembic-customprops-read
https://developer.blender.org/rBfed050922a78d4779d128224f216c9e5ef040f71
Alembic: Added support for reading animated custom properties
This always creates a new ID property when reading a custom property value,
and swaps it out using IDP_ReplaceInGroup_ex(). Another approach would be
to change the ID property in-place. However, that would require code
duplication and may be tricky to get right without memory leaks in the
case of length-changing strings and arrays.
===================================================================
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/alembic_capi.cc
===================================================================
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index 85f247aeecb..2c57af25c1b 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -1372,20 +1372,25 @@ DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm,
/* ******* Custom properties support **************************************** */
-void AbcMeshReader::read_custom_properties(const Alembic::Abc::ISampleSelector &sample_sel)
+void AbcMeshReader::read_custom_properties(const Alembic::Abc::ISampleSelector &sample_sel,
+ bool &r_is_constant)
{
- AbcObjectReader::read_custom_properties(sample_sel);
+ AbcObjectReader::read_custom_properties(sample_sel, r_is_constant);
read_custom_properties_into(static_cast<ID *>(m_object->data),
m_schema.getArbGeomParams(),
- sample_sel);
+ sample_sel,
+ r_is_constant);
}
-void AbcSubDReader::read_custom_properties(const Alembic::Abc::ISampleSelector &sample_sel)
+void AbcSubDReader::read_custom_properties(const Alembic::Abc::ISampleSelector &sample_sel,
+ bool &r_is_constant)
{
- AbcObjectReader::read_custom_properties(sample_sel);
+ AbcObjectReader::read_custom_properties(sample_sel, r_is_constant);
read_custom_properties_into(static_cast<ID *>(m_object->data),
m_schema.getArbGeomParams(),
- sample_sel);
+ sample_sel,
+ r_is_constant);
+}
}
diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h
index 57d116b5eb6..fa2444e9279 100644
--- a/source/blender/alembic/intern/abc_mesh.h
+++ b/source/blender/alembic/intern/abc_mesh.h
@@ -109,7 +109,8 @@ public:
const Alembic::Abc::ISampleSelector &sample_sel,
int read_flag,
const char **err_str);
- virtual void read_custom_properties(const Alembic::Abc::ISampleSelector &sample_sel) override;
+ virtual void read_custom_properties(const Alembic::Abc::ISampleSelector &sample_sel,
+ bool &r_is_constant) override;
private:
void readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start,
const Alembic::AbcGeom::ISampleSelector &sample_sel);
@@ -139,7 +140,8 @@ public:
const Alembic::Abc::ISampleSelector &sample_sel,
int read_flag,
const char **err_str);
- virtual void read_custom_properties(const Alembic::Abc::ISampleSelector &sample_sel) override;
+ virtual void read_custom_properties(const Alembic::Abc::ISampleSelector &sample_sel,
+ bool &r_is_constant) override;
};
/* ************************************************************************** */
diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc
index 767cdd8b2b6..9b5d568016b 100644
--- a/source/blender/alembic/intern/abc_object.cc
+++ b/source/blender/alembic/intern/abc_object.cc
@@ -297,9 +297,12 @@ void AbcObjectReader::read_matrix(float r_mat[4][4], const float time,
using Alembic::Abc::ISampleSelector;
ISampleSelector sample_sel(time, ISampleSelector::kFloorIndex);
+ /* it's only manipulated by &=, so we have to start with true. */
+ is_constant = true;
+
/* Read custom properties before checking the Xform for validity,
* as subclasses might override and read from other things. */
- read_custom_properties(sample_sel);
+ read_custom_properties(sample_sel, is_constant);
IXform ixform = xform();
if (!ixform) {
@@ -333,7 +336,7 @@ void AbcObjectReader::read_matrix(float r_mat[4][4], const float time,
mul_m4_m4m4(r_mat, r_mat, scale_mat);
}
- is_constant = schema.isConstant();
+ is_constant &= schema.isConstant();
}
void AbcObjectReader::addCacheModifier()
@@ -382,28 +385,46 @@ void AbcObjectReader::decref()
* Below 'sl' means 'scalar like', a concept of Alembic properties indicating
* single-valued arrays. Houdini, Maya, etc. write singleton values as
* arrays, so we read them as singleton values as well. */
+
+static IDProperty *IDP_SetOrCreate(ID *id,
+ char idp_type,
+ IDPropertyTemplate &idval,
+ const PropertyHeader &header)
+{
+ const char *propname = header.getName().c_str();
+ IDProperty *group = IDP_GetProperties(id, true);
+ IDProperty *existing = IDP_GetPropertyFromGroup(group, propname);
+ IDProperty *newprop = IDP_New(idp_type, &idval, propname);
+
+ IDP_ReplaceInGroup_ex(group, newprop, existing);
+ return newprop;
+}
+
template<typename ABCTYPE>
-static IDProperty *read_array_sl_int(const PropertyHeader &header,
+static IDProperty *read_array_sl_int(ID *id,
+ 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());
+ return IDP_SetOrCreate(id, IDP_INT, idval, header);
}
template<typename ABCTYPE>
-static IDProperty *read_array_sl_float(const PropertyHeader &header,
+static IDProperty *read_array_sl_float(ID *id,
+ 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());
+ return IDP_SetOrCreate(id, IDP_FLOAT, idval, header);
}
template<typename ABCTYPE, typename BLTYPE>
-static IDProperty *read_array(char idp_type,
+static IDProperty *read_array(ID *id,
+ char idp_type,
const PropertyHeader &header,
Alembic::Util::Dimensions dim,
ArraySamplePtr val)
@@ -413,32 +434,38 @@ static IDProperty *read_array(char idp_type,
IDPropertyTemplate idval = { 0 };
idval.array.len = dim.numPoints();
idval.array.type = idp_type;
- IDProperty *iddata = IDP_New(IDP_ARRAY, &idval, header.getName().c_str());
+ IDProperty *iddata = IDP_SetOrCreate(id, IDP_ARRAY, idval, header);
BLTYPE *array = (BLTYPE *)IDP_Array(iddata);
/* We can't use memcpy here, because the types might need conversion. */
const size_t num = dim.numPoints();
- for (size_t i=0; i < num; i++)
+ for (size_t i=0; i < num; i++) {
+ std::cerr << " - val[" << i << "] = " << data[i] << "\n";
array[i] = data[i];
+ }
return iddata;
}
template<typename ABCPROPTYPE>
-static IDProperty *read_scalar_int(ICompoundProperty params,
+static IDProperty *read_int(ID *id,
+ ICompoundProperty params,
const PropertyHeader &header,
- const Alembic::Abc::ISampleSelector &sample_sel)
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ bool &r_is_constant)
{
ABCPROPTYPE abcprop(params, header.getName());
+ r_is_constant &= abcprop.isConstant();
IDPropertyTemplate idval = { 0 };
idval.i = abcprop.getValue(sample_sel);
- return IDP_New(IDP_INT, &idval, header.getName().c_str());
+ return IDP_SetOrCreate(id, IDP_INT, idval, header);
}
void AbcObjectReader::read_custom_properties_into(ID *id,
ICompoundProperty params,
- const Alembic::Abc::ISampleSelector &sample_sel)
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ bool &r_is_const)
{
/* For all the Alembic data types like uint8_t. */
using namespace Alembic::Util;
@@ -468,6 +495,7 @@ void AbcObjectReader::read_custom_properties_into(ID *id,
if (header.isArray()) {
std::cerr << " - POD: " << header.getDataType().getPod() << "\n";
IArrayProperty ap(params, header.getName());
+ r_is_const &= ap.isConstant();
ArraySamplePtr val;
ap.get(val, sample_sel);
@@ -480,31 +508,31 @@ void AbcObjectReader::read_custom_properties_into(ID *id,
/* Inspired by ArrayPropertyTests.cpp in the Alembic source code. */
switch (header.getDataType().getPod()) {
case kBooleanPOD:
- iddata = read_array_sl_int<bool_t>(header, val);
+ iddata = read_array_sl_int<bool_t>(id, header, val);
break;
case kUint8POD:
- iddata = read_array_sl_int<uint8_t>(header, val);
+ iddata = read_array_sl_int<uint8_t>(id, header, val);
break;
case kInt8POD:
- iddata = read_array_sl_int<int8_t>(header, val);
+ iddata = read_array_sl_int<int8_t>(id, header, val);
break;
case kUint16POD:
- iddata = read_array_sl_int<uint16_t>(header, val);
+ iddata = read_array_sl_int<uint16_t>(id, header, val);
break;
case kInt16POD:
- iddata = read_array_sl_int<int16_t>(header, val);
+ iddata = read_array_sl_int<int16_t>(id, header, val);
break;
case kUint32POD:
- iddata = read_array_sl_int<uint32_t>(header, val);
+ iddata = read_array_sl_int<uint32_t>(id, header, val);
break;
case kInt32POD:
- iddata = read_array_sl_int<int32_t>(header, val);
+ iddata = read_array_sl_int<int32_t>(id, header, val);
break;
case kFloat16POD:
- iddata = read_array_sl_float<float16_t>(header, val);
+ iddata = read_array_sl_float<float16_t>(id, header, val);
break;
case kFloat32POD:
- iddata = read_array_sl_float<float32_t>(header, val);
+ iddata = read_array_sl_float<float32_t>(id, header, val);
break;
case kStringPOD:
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list