[Bf-blender-cvs] [05d38c4a995] temp-T50725-alembic-export-custom-properties: Avoid breakage when there are no custom properties to be written

Sybren A. Stüvel noreply at git.blender.org
Thu Sep 10 19:45:40 CEST 2020


Commit: 05d38c4a995a3bd6c6578e3fee8c2d925bdc9136
Author: Sybren A. Stüvel
Date:   Thu Sep 10 19:44:49 2020 +0200
Branches: temp-T50725-alembic-export-custom-properties
https://developer.blender.org/rB05d38c4a995a3bd6c6578e3fee8c2d925bdc9136

Avoid breakage when there are no custom properties to be written

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

M	source/blender/io/alembic/exporter/abc_custom_props.cc
M	source/blender/io/alembic/exporter/abc_custom_props.h
M	source/blender/io/alembic/exporter/abc_writer_abstract.cc
M	source/blender/io/alembic/exporter/abc_writer_abstract.h
M	source/blender/io/alembic/exporter/abc_writer_camera.cc
M	source/blender/io/alembic/exporter/abc_writer_camera.h
M	source/blender/io/alembic/exporter/abc_writer_curves.cc
M	source/blender/io/alembic/exporter/abc_writer_curves.h
M	source/blender/io/alembic/exporter/abc_writer_hair.cc
M	source/blender/io/alembic/exporter/abc_writer_hair.h
M	source/blender/io/alembic/exporter/abc_writer_instance.cc
M	source/blender/io/alembic/exporter/abc_writer_instance.h
M	source/blender/io/alembic/exporter/abc_writer_mesh.cc
M	source/blender/io/alembic/exporter/abc_writer_mesh.h
M	source/blender/io/alembic/exporter/abc_writer_nurbs.cc
M	source/blender/io/alembic/exporter/abc_writer_nurbs.h
M	source/blender/io/alembic/exporter/abc_writer_points.cc
M	source/blender/io/alembic/exporter/abc_writer_points.h
M	source/blender/io/alembic/exporter/abc_writer_transform.cc
M	source/blender/io/alembic/exporter/abc_writer_transform.h
M	tests/python/alembic_export_tests.py

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

diff --git a/source/blender/io/alembic/exporter/abc_custom_props.cc b/source/blender/io/alembic/exporter/abc_custom_props.cc
index d4410b52798..2d9525d0a1d 100644
--- a/source/blender/io/alembic/exporter/abc_custom_props.cc
+++ b/source/blender/io/alembic/exporter/abc_custom_props.cc
@@ -23,6 +23,8 @@
 
 #include "abc_custom_props.h"
 
+#include "abc_writer_abstract.h"
+
 #include <functional>
 #include <iostream>
 #include <memory>
@@ -37,6 +39,7 @@
 using Alembic::Abc::ArraySample;
 using Alembic::Abc::OArrayProperty;
 using Alembic::Abc::OBoolArrayProperty;
+using Alembic::Abc::OCompoundProperty;
 using Alembic::Abc::ODoubleArrayProperty;
 using Alembic::Abc::OFloatArrayProperty;
 using Alembic::Abc::OInt32ArrayProperty;
@@ -44,9 +47,9 @@ using Alembic::Abc::OStringArrayProperty;
 
 namespace blender::io::alembic {
 
-CustomPropertiesExporter::CustomPropertiesExporter(
-    Alembic::Abc::OCompoundProperty abc_compound_prop, uint32_t timesample_index)
-    : abc_compound_prop_(abc_compound_prop), timesample_index_(timesample_index)
+CustomPropertiesExporter::CustomPropertiesExporter(ABCAbstractWriter *owner,
+                                                   uint32_t timesample_index)
+    : owner_(owner), timesample_index_(timesample_index)
 {
 }
 
@@ -243,7 +246,8 @@ void CustomPropertiesExporter::set_array_property(const StringRef property_name,
 {
   /* Create an Alembic property if it doesn't exist yet. */
   auto create_callback = [this, property_name]() -> OArrayProperty {
-    ABCPropertyType abc_property(abc_compound_prop_, property_name);
+    OCompoundProperty abc_user_props = owner_->abc_user_props();
+    ABCPropertyType abc_property(abc_user_props, property_name);
     abc_property.setTimeSampling(timesample_index_);
     return abc_property;
   };
diff --git a/source/blender/io/alembic/exporter/abc_custom_props.h b/source/blender/io/alembic/exporter/abc_custom_props.h
index 2c096afcb08..55f3dc3d323 100644
--- a/source/blender/io/alembic/exporter/abc_custom_props.h
+++ b/source/blender/io/alembic/exporter/abc_custom_props.h
@@ -34,10 +34,14 @@ struct IDProperty;
 
 namespace blender::io::alembic {
 
+class ABCAbstractWriter;
+
 /* Write values of Custom Properties (a.k.a. ID Properties) to Alembic.
  * Create the appropriate Alembic objects for the property types. */
 class CustomPropertiesExporter {
  private:
+  ABCAbstractWriter *owner_;
+
   /* The Compound Property that will contain the exported custom properties.
    *
    * Typically this the return value of Abc::OSchema::getArbGeomParams() or
@@ -52,8 +56,7 @@ class CustomPropertiesExporter {
   uint32_t timesample_index_;
 
  public:
-  CustomPropertiesExporter(Alembic::Abc::OCompoundProperty abc_compound_prop,
-                           uint32_t timesample_index);
+  CustomPropertiesExporter(ABCAbstractWriter *owner, uint32_t timesample_index);
   virtual ~CustomPropertiesExporter();
 
   void write_all(const IDProperty *group);
diff --git a/source/blender/io/alembic/exporter/abc_writer_abstract.cc b/source/blender/io/alembic/exporter/abc_writer_abstract.cc
index bdae946de66..530fe58c101 100644
--- a/source/blender/io/alembic/exporter/abc_writer_abstract.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_abstract.cc
@@ -54,17 +54,12 @@ bool ABCAbstractWriter::is_supported(const HierarchyContext * /*context*/) const
   return true;
 }
 
-void ABCAbstractWriter::create_custom_properties_exporter(
-    Alembic::Abc::OCompoundProperty abc_compound_prop)
-{
-  custom_props_ = std::make_unique<CustomPropertiesExporter>(abc_compound_prop, timesample_index_);
-}
-
 void ABCAbstractWriter::write(HierarchyContext &context)
 {
   if (!frame_has_been_written_) {
     is_animated_ = (args_.export_params->frame_start != args_.export_params->frame_end) &&
                    check_is_animated(context);
+    ensure_custom_properties_exporter(context);
   }
   else if (!is_animated_) {
     /* A frame has already been written, and without animation one frame is enough. */
@@ -80,6 +75,21 @@ void ABCAbstractWriter::write(HierarchyContext &context)
   frame_has_been_written_ = true;
 }
 
+void ABCAbstractWriter::ensure_custom_properties_exporter(const HierarchyContext &context)
+{
+  if (custom_props_) {
+    /* Custom properties exporter already created. */
+    return;
+  }
+
+  /* Avoid creating a custom properties exporter if there are no custom properties to export. */
+  const IDProperty *id_properties = get_id_properties(context);
+  if (id_properties == nullptr || id_properties->len == 0) {
+    return;
+  }
+  custom_props_ = std::make_unique<CustomPropertiesExporter>(this, timesample_index_);
+}
+
 const IDProperty *ABCAbstractWriter::get_id_properties(const HierarchyContext &context) const
 {
   Object *object = context.object;
@@ -91,6 +101,11 @@ const IDProperty *ABCAbstractWriter::get_id_properties(const HierarchyContext &c
   return static_cast<ID *>(object->data)->properties;
 }
 
+// Alembic::Abc::OCompoundProperty ABCAbstractWriter::abc_user_props()
+// {
+//   return Alembic::Abc::OCompoundProperty();
+// }
+
 const Imath::Box3d &ABCAbstractWriter::bounding_box() const
 {
   return bounding_box_;
diff --git a/source/blender/io/alembic/exporter/abc_writer_abstract.h b/source/blender/io/alembic/exporter/abc_writer_abstract.h
index ec868b93c3e..94bee54e9e5 100644
--- a/source/blender/io/alembic/exporter/abc_writer_abstract.h
+++ b/source/blender/io/alembic/exporter/abc_writer_abstract.h
@@ -71,6 +71,15 @@ class ABCAbstractWriter : public AbstractHierarchyWriter {
 
   virtual Alembic::Abc::OObject get_alembic_object() const = 0;
 
+  /* Return the Alembic object's .userParameters property.
+   *
+   * This function is called whenever there are custom properties to be written
+   * to Alembic. The Alembic library will write an invalid Alembic file when
+   * .getUserProperties() is called without actually using the return value to
+   * add any properties, which is why this function is only called on demand.
+   */
+  virtual Alembic::Abc::OCompoundProperty abc_user_props() = 0;
+
  protected:
   virtual void do_write(HierarchyContext &context) = 0;
 
@@ -81,7 +90,8 @@ class ABCAbstractWriter : public AbstractHierarchyWriter {
    */
   virtual const IDProperty *get_id_properties(const HierarchyContext &context) const;
 
-  void create_custom_properties_exporter(Alembic::Abc::OCompoundProperty abc_compound_prop);
+  virtual void ensure_custom_properties_exporter(const HierarchyContext &context);
+
   void write_visibility(const HierarchyContext &context);
 };
 
diff --git a/source/blender/io/alembic/exporter/abc_writer_camera.cc b/source/blender/io/alembic/exporter/abc_writer_camera.cc
index ac0ec3715a0..1c9c91bac4f 100644
--- a/source/blender/io/alembic/exporter/abc_writer_camera.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_camera.cc
@@ -52,7 +52,6 @@ void ABCCameraWriter::create_alembic_objects(const HierarchyContext * /*context*
   CLOG_INFO(&LOG, 2, "exporting %s", args_.abc_path.c_str());
   abc_camera_ = OCamera(args_.abc_parent, args_.abc_name, timesample_index_);
   abc_camera_schema_ = abc_camera_.getSchema();
-  create_custom_properties_exporter(abc_camera_schema_.getUserProperties());
 
   abc_custom_data_container_ = abc_camera_schema_.getUserProperties();
   abc_stereo_distance_ = OFloatProperty(
@@ -66,6 +65,11 @@ Alembic::Abc::OObject ABCCameraWriter::get_alembic_object() const
   return abc_camera_;
 }
 
+Alembic::Abc::OCompoundProperty ABCCameraWriter::abc_user_props()
+{
+  return abc_camera_schema_.getUserProperties();
+}
+
 void ABCCameraWriter::do_write(HierarchyContext &context)
 {
   Camera *cam = static_cast<Camera *>(context.object->data);
diff --git a/source/blender/io/alembic/exporter/abc_writer_camera.h b/source/blender/io/alembic/exporter/abc_writer_camera.h
index 1b3e5898517..b2b36c6459a 100644
--- a/source/blender/io/alembic/exporter/abc_writer_camera.h
+++ b/source/blender/io/alembic/exporter/abc_writer_camera.h
@@ -43,6 +43,7 @@ class ABCCameraWriter : public ABCAbstractWriter {
  protected:
   virtual bool is_supported(const HierarchyContext *context) const override;
   virtual void do_write(HierarchyContext &context) override;
+  Alembic::Abc::OCompoundProperty abc_user_props() override;
 };
 
 }  // namespace blender::io::alembic
diff --git a/source/blender/io/alembic/exporter/abc_writer_curves.cc b/source/blender/io/alembic/exporter/abc_writer_curves.cc
index 6a12e4c59f3..e37306669ea 100644
--- a/source/blender/io/alembic/exporter/abc_writer_curves.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_curves.cc
@@ -66,6 +66,11 @@ Alembic::Abc::OObject ABCCurveWriter::get_alembic_object() const
   return abc_curve_;
 }
 
+Alembic::Abc::OCompoundProperty ABCCurveWriter::abc_user_props()
+{
+  return abc_curve_schema_.getUserProperties();
+}
+
 void ABCCurveWriter::do_write(HierarchyContext &context)
 {
   Curve *curve = static_cast<Curve *>(context.object->data);
diff --git a/source/blender/io/alembic/exporter/abc_writer_curves.h b/source/blender/io/alembic/exporter/abc_writer_curves.h
index d15f008f947..1a0239db014 100644
--- a/source/blender/io/alembic/exporter/abc_writer_curves.h
+++ b/source/blender/io/alembic/exporter/abc_writer_curves.h
@@ -41,6 +41,7 @@ class ABCCurveWriter : public ABCAbstractWriter {
 
   virtual void create_alembic_objects(const HierarchyContext *context) override;
   virtual Alembic::Abc::OObject get_alembic_object() const override;
+  Alembic::Abc::OCompoundProperty abc_user_props() override;
 
  protected:
   virtual void do_write(HierarchyContext &context) override;
diff --git a/source/blender/io/alembic/exporter/abc_writer_hair.cc b/source/blender/io/alembic/exporter/abc_writer_hair.cc
index 80034245b84..0488b2dc76c 100644
--- a/source/blender/io/alembic/exporter/abc_writer_hair.cc
+++ b/source/blender/io/alembic/exporter/abc_writer_hair.cc
@@ -62,6 +62,11 @@ Alembic::Abc::OObject ABCHairWriter::get_alembic_object() const
   return abc_curves_;
 }
 
+Alembic::Abc::OCompoundProperty ABCHairWriter::abc_user_props()
+{
+  return abc_curves_schema_.getUserProperties();
+}
+
 bool ABCHairWriter::check_is_animated(const HierarchyContext & /*context*/) const
 {
   /* We assume that hair particles 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list