[Bf-blender-cvs] [b3759cc0d67] master: Alembic Export: support instanced object data

Sybren A. Stüvel noreply at git.blender.org
Tue Sep 8 16:47:43 CEST 2020


Commit: b3759cc0d67eeb8cec55314d3304db0bc02168af
Author: Sybren A. Stüvel
Date:   Tue Sep 8 16:15:49 2020 +0200
Branches: master
https://developer.blender.org/rBb3759cc0d67eeb8cec55314d3304db0bc02168af

Alembic Export: support instanced object data

Add support for object data instancing. This is used when the objects
are instances, for example when duplicated by a particle system, or
instanced by the duplication system (collection-duplicating empties,
vertex/face duplis, etc.)

Since Alembic already deduplicates data, this doesn't make the resulting
Alembic files any smaller. They will be faster to write, though, when
there is a lot of instanced geometry, as the deduplication system won't
have to do any comparisons.

This instancing support is still limited, in the sense that only object
data is instanced and all transforms are still written explicitly. A
future improvement could be to support instancing entire collection
hierarchies.

Blender's Alembic importer has no understanding of these Alembic
instances yet, and will thus happily duplicate the data on import.

The USD Alembic plugin seems to have problems understanding the
instancing. There might also be other software with similar issues.
Because of this, instancing can be turned off in the exporter (it's on
by default).

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

M	source/blender/editors/io/io_alembic.c
M	source/blender/io/alembic/ABC_alembic.h
M	source/blender/io/alembic/CMakeLists.txt
M	source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc
A	source/blender/io/alembic/exporter/abc_writer_instance.cc
A	source/blender/io/alembic/exporter/abc_writer_instance.h

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

diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c
index 22171d8be66..0c4064b5693 100644
--- a/source/blender/editors/io/io_alembic.c
+++ b/source/blender/editors/io/io_alembic.c
@@ -133,6 +133,7 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op)
       .use_subdiv_schema = RNA_boolean_get(op->ptr, "subdiv_schema"),
       .export_hair = RNA_boolean_get(op->ptr, "export_hair"),
       .export_particles = RNA_boolean_get(op->ptr, "export_particles"),
+      .use_instancing = RNA_boolean_get(op->ptr, "use_instancing"),
       .packuv = RNA_boolean_get(op->ptr, "packuv"),
       .triangulate = RNA_boolean_get(op->ptr, "triangulate"),
       .quad_method = RNA_enum_get(op->ptr, "quad_method"),
@@ -189,6 +190,7 @@ static void ui_alembic_export_settings(uiLayout *layout, PointerRNA *imfptr)
   uiItemS(col);
 
   uiItemR(col, imfptr, "flatten", 0, NULL, ICON_NONE);
+  uiItemR(sub, imfptr, "use_instancing", 0, IFACE_("Use Instancing"), ICON_NONE);
   sub = uiLayoutColumnWithHeading(col, true, IFACE_("Only"));
   uiItemR(sub, imfptr, "selected", 0, IFACE_("Selected Objects"), ICON_NONE);
   uiItemR(sub, imfptr, "renderable_only", 0, IFACE_("Renderable Objects"), ICON_NONE);
@@ -401,6 +403,13 @@ void WM_OT_alembic_export(wmOperatorType *ot)
                   "Curves as Mesh",
                   "Export curves and NURBS surfaces as meshes");
 
+  RNA_def_boolean(ot->srna,
+                  "use_instancing",
+                  true,
+                  "Use Instancing",
+                  "Export data of duplicated objects as Alembic instances; speeds up the export "
+                  "and can be disabled for compatibility with other software");
+
   RNA_def_float(
       ot->srna,
       "global_scale",
diff --git a/source/blender/io/alembic/ABC_alembic.h b/source/blender/io/alembic/ABC_alembic.h
index 28e3d0dd1f5..9a2c74c64a3 100644
--- a/source/blender/io/alembic/ABC_alembic.h
+++ b/source/blender/io/alembic/ABC_alembic.h
@@ -60,6 +60,7 @@ struct AlembicExportParams {
   bool triangulate;
   bool export_hair;
   bool export_particles;
+  bool use_instancing;
 
   /* See MOD_TRIANGULATE_NGON_xxx and MOD_TRIANGULATE_QUAD_xxx
    * in DNA_modifier_types.h */
diff --git a/source/blender/io/alembic/CMakeLists.txt b/source/blender/io/alembic/CMakeLists.txt
index de99a2c9d65..2b44146e475 100644
--- a/source/blender/io/alembic/CMakeLists.txt
+++ b/source/blender/io/alembic/CMakeLists.txt
@@ -63,6 +63,7 @@ set(SRC
   exporter/abc_writer_camera.cc
   exporter/abc_writer_curves.cc
   exporter/abc_writer_hair.cc
+  exporter/abc_writer_instance.cc
   exporter/abc_writer_mball.cc
   exporter/abc_writer_mesh.cc
   exporter/abc_writer_nurbs.cc
@@ -89,6 +90,7 @@ set(SRC
   exporter/abc_writer_camera.h
   exporter/abc_writer_curves.h
   exporter/abc_writer_hair.h
+  exporter/abc_writer_instance.h
   exporter/abc_writer_mball.h
   exporter/abc_writer_mesh.h
   exporter/abc_writer_nurbs.h
diff --git a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc
index 5fc5c47d4b9..4cb6ca0c601 100644
--- a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc
+++ b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc
@@ -22,6 +22,7 @@
 #include "abc_writer_camera.h"
 #include "abc_writer_curves.h"
 #include "abc_writer_hair.h"
+#include "abc_writer_instance.h"
 #include "abc_writer_mball.h"
 #include "abc_writer_mesh.h"
 #include "abc_writer_nurbs.h"
@@ -181,7 +182,14 @@ AbstractHierarchyWriter *ABCHierarchyIterator::create_transform_writer(
 AbstractHierarchyWriter *ABCHierarchyIterator::create_data_writer(const HierarchyContext *context)
 {
   const ABCWriterConstructorArgs writer_args = writer_constructor_args(context);
-  ABCAbstractWriter *data_writer = create_data_writer_for_object_type(context, writer_args);
+  ABCAbstractWriter *data_writer = nullptr;
+
+  if (params_.use_instancing && context->is_instance()) {
+    data_writer = new ABCInstanceWriter(writer_args);
+  }
+  else {
+    data_writer = create_data_writer_for_object_type(context, writer_args);
+  }
 
   if (data_writer == nullptr || !data_writer->is_supported(context)) {
     delete data_writer;
diff --git a/source/blender/io/alembic/exporter/abc_writer_instance.cc b/source/blender/io/alembic/exporter/abc_writer_instance.cc
new file mode 100644
index 00000000000..581d94ee961
--- /dev/null
+++ b/source/blender/io/alembic/exporter/abc_writer_instance.cc
@@ -0,0 +1,74 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup balembic
+ */
+
+#include "abc_writer_instance.h"
+#include "abc_hierarchy_iterator.h"
+
+#include "BLI_assert.h"
+
+#include "CLG_log.h"
+static CLG_LogRef LOG = {"io.alembic"};
+
+namespace blender {
+namespace io {
+namespace alembic {
+
+using Alembic::Abc::OObject;
+
+ABCInstanceWriter::ABCInstanceWriter(const ABCWriterConstructorArgs &args)
+    : ABCAbstractWriter(args)
+{
+}
+
+ABCInstanceWriter::~ABCInstanceWriter()
+{
+}
+
+void ABCInstanceWriter::create_alembic_objects(const HierarchyContext *context)
+{
+  OObject original = args_.hierarchy_iterator->get_alembic_object(context->original_export_path);
+  OObject abc_parent = args_.abc_parent;
+  if (!abc_parent.addChildInstance(original, args_.abc_name)) {
+    CLOG_WARN(&LOG, "unable to export %s as instance", args_.abc_path.c_str());
+    return;
+  }
+  CLOG_INFO(&LOG, 2, "exporting instance %s", args_.abc_path.c_str());
+}
+
+OObject ABCInstanceWriter::get_alembic_object() const
+{
+  /* There is no OObject for an instance. */
+  BLI_assert(!"ABCInstanceWriter cannot return its Alembic OObject");
+  return OObject();
+}
+
+bool ABCInstanceWriter::is_supported(const HierarchyContext *context) const
+{
+  return context->is_instance();
+}
+
+void ABCInstanceWriter::do_write(HierarchyContext & /*context*/)
+{
+  /* Instances don't have data to be written. Just creating them is enough. */
+}
+
+}  // namespace alembic
+}  // namespace io
+}  // namespace blender
diff --git a/source/blender/io/alembic/exporter/abc_writer_instance.h b/source/blender/io/alembic/exporter/abc_writer_instance.h
new file mode 100644
index 00000000000..74379b9d6bd
--- /dev/null
+++ b/source/blender/io/alembic/exporter/abc_writer_instance.h
@@ -0,0 +1,48 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+#pragma once
+
+/** \file
+ * \ingroup balembic
+ */
+
+#include "abc_writer_abstract.h"
+
+namespace blender {
+namespace io {
+namespace alembic {
+
+/* Writer for Alembic instances, i.e. data that references another Alembic object.
+ *
+ * Note that the Alembic object created by this writer cannot be used as a
+ * parent, because it already instantiates the entire hierarchy of the
+ * referenced object. */
+class ABCInstanceWriter : public ABCAbstractWriter {
+ public:
+  explicit ABCInstanceWriter(const ABCWriterConstructorArgs &args);
+  virtual ~ABCInstanceWriter();
+
+  virtual void create_alembic_objects(const HierarchyContext *context) override;
+  virtual Alembic::Abc::OObject get_alembic_object() const override;
+
+ protected:
+  virtual bool is_supported(const HierarchyContext *context) const override;
+  virtual void do_write(HierarchyContext &context) override;
+};
+
+}  // namespace alembic
+}  // namespace io
+}  // namespace blender



More information about the Bf-blender-cvs mailing list