[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