[Bf-blender-cvs] [ca1aae3e7bf] temp-T50725-alembic-export-custom-properties: Support for matrices of type double
Sybren A. Stüvel
noreply at git.blender.org
Thu Sep 10 19:45:40 CEST 2020
Commit: ca1aae3e7bf9f0c2c61fe6d6fd54cf0c4042016d
Author: Sybren A. Stüvel
Date: Thu Sep 10 16:09:33 2020 +0200
Branches: temp-T50725-alembic-export-custom-properties
https://developer.blender.org/rBca1aae3e7bf9f0c2c61fe6d6fd54cf0c4042016d
Support for matrices of type double
===================================================================
M source/blender/io/alembic/exporter/abc_custom_props.cc
M source/blender/io/alembic/exporter/abc_custom_props.h
===================================================================
diff --git a/source/blender/io/alembic/exporter/abc_custom_props.cc b/source/blender/io/alembic/exporter/abc_custom_props.cc
index 17439007129..6962e801590 100644
--- a/source/blender/io/alembic/exporter/abc_custom_props.cc
+++ b/source/blender/io/alembic/exporter/abc_custom_props.cc
@@ -25,6 +25,7 @@
#include <functional>
#include <iostream>
+#include <memory>
#include <string>
#include <Alembic/Abc/OTypedArrayProperty.h>
@@ -53,45 +54,49 @@ CustomPropertiesExporter::~CustomPropertiesExporter()
{
}
-namespace {
-
-/* Callback for IDP_foreach_property() that just calls CustomPropertiesExporter::write(). */
-void customPropertiesExporter_write(IDProperty *id_property, void *user_data)
-{
- CustomPropertiesExporter *exporter = reinterpret_cast<CustomPropertiesExporter *>(user_data);
- exporter->write(id_property);
-};
-
-} // namespace
-
void CustomPropertiesExporter::write_all(IDProperty *group)
{
if (group == nullptr) {
std::cout << "CustomPropertiesExporter::write_all(nullptr)\n";
return;
}
- std::cout << "CustomPropertiesExporter::write_all(" << group->name << ")\n";
- IDP_foreach_property(group,
- IDP_TYPE_FILTER_STRING | IDP_TYPE_FILTER_INT | IDP_TYPE_FILTER_FLOAT |
- IDP_TYPE_FILTER_ARRAY | IDP_TYPE_FILTER_DOUBLE,
- customPropertiesExporter_write,
- this);
+ std::cout << "CustomPropertiesExporter::write_all()\n";
+ BLI_assert(group->type = IDP_GROUP);
+
+ /* Loop over the properties, just like IDP_foreach_property() does but without the recursion. */
+ LISTBASE_FOREACH (IDProperty *, id_property, &group->data.group) {
+ if (STREQ(id_property->name, "_RNA_UI")) {
+ continue;
+ }
+ write(id_property);
+ }
+
std::cout << "\n";
}
void CustomPropertiesExporter::write(IDProperty *id_property)
{
std::cout << " CustomPropertiesExporter::write(" << id_property->name << " ";
+
+ if (id_property->name[0] == '\0') {
+ strcpy(id_property->name, "NONAME");
+ std::cout << "\033[95mskip nameless of type " << id_property->type << "\033[0m)\n";
+ /* This happens when custom properties are pointing to things like mathutils.Matrix. Not sure
+ * why they don't get a name then, though. */
+ return;
+ }
+
switch (id_property->type) {
case IDP_STRING: {
std::cout << "string";
/* The Alembic library doesn't accept NULL-terminated character arrays. */
- const std::string prop_value = IDP_String(id_property);
+ const std::string prop_value(IDP_String(id_property), id_property->len - 1);
set_scalar_property<OStringArrayProperty, std::string>(id_property->name, prop_value);
break;
}
case IDP_INT:
std::cout << "int";
+ static_assert(sizeof(int) == sizeof(int32_t), "Expecting 'int' to be 32-bit");
set_scalar_property<OInt32ArrayProperty, int32_t>(id_property->name, IDP_Int(id_property));
break;
case IDP_FLOAT:
@@ -104,46 +109,219 @@ void CustomPropertiesExporter::write(IDProperty *id_property)
IDP_Double(id_property));
break;
case IDP_ARRAY:
- switch (id_property->subtype) {
- case IDP_INT: {
- std::cout << "int[]";
- const int *array = (int *)IDP_Array(id_property);
- set_array_property<OInt32ArrayProperty, int32_t>(
- id_property->name, array, id_property->len);
- break;
- }
- case IDP_FLOAT: {
- std::cout << "float[]";
- const float *array = (float *)IDP_Array(id_property);
- set_array_property<OFloatArrayProperty, float>(
- id_property->name, array, id_property->len);
- break;
- }
- case IDP_DOUBLE: {
- std::cout << "double[]";
- const double *array = (double *)IDP_Array(id_property);
- set_array_property<ODoubleArrayProperty, double>(
- id_property->name, array, id_property->len);
- break;
- }
- case IDP_ARRAY:
- case IDP_GROUP:
- case IDP_ID:
- case IDP_IDPARRAY:
- std::cout << "\033[91munsupported[]\033[0m)\n";
- /* Unsupported. */
- break;
- }
+ write_array(id_property);
+ break;
+ case IDP_IDPARRAY:
+ write_idparray(id_property);
+ break;
+
+ /* Unsupported: */
+ case IDP_GROUP:
+ case IDP_ID:
+ std::cout << "\033[91munsupported type " << (uint16_t)id_property->type << "\033[0m)\n";
+ break;
+ }
+}
+
+void CustomPropertiesExporter::write_array(IDProperty *id_property)
+{
+ BLI_assert(id_property->type == IDP_ARRAY);
+
+ switch (id_property->subtype) {
+ case IDP_INT: {
+ std::cout << "int[]";
+ const int *array = (int *)IDP_Array(id_property);
+ static_assert(sizeof(int) == sizeof(int32_t), "Expecting 'int' to be 32-bit");
+ set_array_property<OInt32ArrayProperty, int32_t>(id_property->name, array, id_property->len);
+ break;
+ }
+ case IDP_FLOAT: {
+ std::cout << "float[]";
+ const float *array = (float *)IDP_Array(id_property);
+ set_array_property<OFloatArrayProperty, float>(id_property->name, array, id_property->len);
+ break;
+ }
+ case IDP_DOUBLE: {
+ std::cout << "double[]";
+ const double *array = (double *)IDP_Array(id_property);
+ set_array_property<ODoubleArrayProperty, double>(id_property->name, array, id_property->len);
+ break;
+ }
+
+ /* Unsupported: */
+ case IDP_ARRAY:
+ std::cout << "\033[91marray-of-arrays\033[0m\n";
+ break;
+ case IDP_GROUP:
+ std::cout << "\033[91marray-of-groups\033[0m\n";
+ break;
+ case IDP_ID:
+ std::cout << "\033[91marray-of-IDs\033[0m\n";
+ break;
+ case IDP_IDPARRAY:
+ std::cout << "\033[91array-of-IDPARRAY\033[0m)\n";
+ break;
+ }
+}
+
+void CustomPropertiesExporter::write_idparray(IDProperty *idp_array)
+{
+ BLI_assert(idp_array->type == IDP_IDPARRAY);
+
+ if (idp_array->len == 0) {
+ /* Don't bother writing dataless arrays. */
+ return;
+ }
+
+ IDProperty *idp_elements = (IDProperty *)IDP_Array(idp_array);
+
+#ifndef NDEBUG
+ /* Sanity check that all elements of the array have the same type.
+ * Blender should already enforce this, hence it's only used in debug mode. */
+ for (int i = 1; i < idp_array->len; i++) {
+ if (idp_elements[i].type == idp_elements[0].type) {
+ continue;
+ }
+
+ std::cerr << "Custom property " << idp_array->name << " has elements of varying type";
+ BLI_assert(!"Mixed type IDP_ARRAY custom property found");
+ }
+#endif
+
+ // /* Loop over the array, just like IDP_foreach_property() does but without the recursion. */
+ // IDProperty *loop = IDP_Array(idp_array);
+ // for (int i = 0; i < idp_array->len; i++) {
+ // IDP_foreach_property(&loop[i], type_filter, callback, user_data);
+ // }
+
+ std::cout << "IDPArray of ";
+ switch (idp_elements[0].type) {
+ case IDP_STRING:
+ std::cout << "IDP_STRING";
+ write_idparray_of_strings(idp_array);
+ break;
+ case IDP_ARRAY:
+ std::cout << "IDP_ARRAY: ";
+ write_idparray_matrix(idp_array);
break;
+
+ /* Unsupported. */
+ case IDP_INT:
+ case IDP_FLOAT:
+ case IDP_DOUBLE:
case IDP_GROUP:
case IDP_ID:
case IDP_IDPARRAY:
- std::cout << "\033[91munsupported\033[0m)\n";
- /* Unsupported. */
+ case IDP_NUMTYPES:
+ break;
+ }
+ std::cout << "\n";
+}
+
+void CustomPropertiesExporter::write_idparray_of_strings(IDProperty *idp_array)
+{
+ BLI_assert(idp_array->type == IDP_IDPARRAY);
+ BLI_assert(idp_array->len > 0);
+
+ /* Convert to an array of std::strings, because Alembic doesn't like zero-delimited strings. */
+ IDProperty *idp_elements = (IDProperty *)IDP_Array(idp_array);
+ std::vector<std::string> strings(idp_array->len);
+ for (int i = 0; i < idp_array->len; i++) {
+ BLI_assert(idp_elements[i].type == IDP_STRING);
+ strings[i] = IDP_String(&idp_elements[i]);
+ }
+
+ /* Alembic needs a pointer to the first value of the array. */
+ const std::string *array_of_strings = &strings[0];
+ set_array_property<OStringArrayProperty, std::string>(
+ idp_array->name, array_of_strings, strings.size());
+}
+
+void CustomPropertiesExporter::write_idparray_matrix(IDProperty *idp_array)
+{
+ BLI_assert(idp_array->type == IDP_IDPARRAY);
+ BLI_assert(idp_array->len > 0);
+
+ /* This must be an array of arrays. */
+ IDProperty *idp_rows = (IDProperty *)IDP_Array(idp_array);
+ BLI_assert(idp_rows[0].type == IDP_ARRAY);
+
+ /* This function is made for writing NxM matrices, and doesn't support non-numeric types or rows
+ * of varying length. */
+ const size_t num_rows = idp_array->len;
+ if (num_rows == 0) {
+ return;
+ }
+ const size_t num_cols = idp_rows[0].len;
+ const int subtype = idp_rows[0].subtype;
+ if (!ELEM(subtype, IDP_INT, IDP_FLOAT, IDP_DOUBLE)) {
+ /* Non-numerical types are not supported. */
+ return;
+ }
+
+ /* All rows must have the same length, and have values of the same type. */
+ for (int row_idx = 0; row_idx < num_rows; row_idx++) {
+ const IDProperty &idp_row = idp_rows[0];
+ if (idp_row.subtype != subtype || idp_row.len != num_cols) {
+ return;
+ }
+ }
+
+ std::cout << "matrix[" << num_rows << "][" << num_cols << "]";
+ switch (subtype) {
+ case IDP_INT:
+ write_idparray_matrix_int(idp_array);
+ break;
+ case IDP_FLOAT:
+ write_idparray_matrix_float(idp_array);
+ break;
+ case IDP_DOUBLE:
+ write_idparray_matrix_double(idp_array);
break;
}
}
+void CustomPropertiesExporter::write_idparray_matrix_int(IDProperty * /*idp_array*/)
+{
+ std::cout << "int";
+}
+
+void CustomPropertiesExporter::write_idparray_matrix_float(IDProperty * /*idp_array*/)
+{
+ std::cout << "float";
+}
+
+void CustomPropertiesExporter::write_idparray_matrix_double(IDProperty *idp_array)
+{
+ std::cout << "double";
+ BLI_assert(idp_array->type == IDP_IDPARRAY);
+ BLI_assert(idp_array->len > 0);
+
+ /* This must be an array of arrays of double. */
+ const IDProperty *idp_rows = (IDProper
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list