Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@blender.org>2020-06-19 17:36:10 +0300
committerSybren A. Stüvel <sybren@blender.org>2020-06-30 12:38:46 +0300
commit2917df21adc8a1ce0423349909db61d22a38d451 (patch)
tree35b8ccdf0078fda4f186821b016701f46cb42c86 /source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc
parenta2b7c84ae8eadf5983ee42091ce4e33315ca83ce (diff)
Alembic: new exporter based on the USD exporter structure
The Alembic exporter has been restructured by leverages the `AbstractHierarchyIterator` introduced by the USD exporter. The produced Alembic files have not changed much (details below), as the Alembic writing code has simply been moved from the old exporter to the new. How the export hierarchy is handled changed a lot, though, and also the way in which transforms are computed. As a result, T71395 is fixed. Differences between the old and new exporter, in terms of the produced Alembic file: - Duplicated objects now have a unique numerical suffix. - Matrices are computed differently, namely by simply computing the evaluated transform of the object relative to the evaluated transform of its export-parent. This fixes {T71395}, but otherwise should produce the same result as before (but with simpler code). Compared to the old Alembic exporter, Subdivision modifiers are now disabled in a cleaner, more efficient way (they are disabled when exporting with the "Apply Subdivisions" option is unchecked). Previously the exporter would move to a new frame, disable the modifier, evaluate the object, and enable the modifier again. This is now done before exporting starts, and modifiers are only restored when exporting ends. Some issues with the old Alembic exporter that have NOT been fixed in this patch: - Exporting NURBS patches and curves (see T49114 for example). - Exporting flattened hierarchy in combination with dupli-objects. This seems to be broken in the old Alembic exporter as well, but nobody reported this yet. Differential Revision: https://developer.blender.org/D7664 Reviewed By: Sergey
Diffstat (limited to 'source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc')
-rw-r--r--source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc261
1 files changed, 261 insertions, 0 deletions
diff --git a/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc
new file mode 100644
index 00000000000..90004c0e85b
--- /dev/null
+++ b/source/blender/io/alembic/exporter/abc_hierarchy_iterator.cc
@@ -0,0 +1,261 @@
+/*
+ * 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.
+ *
+ * The Original Code is Copyright (C) 2020 Blender Foundation.
+ * All rights reserved.
+ */
+
+#include "abc_hierarchy_iterator.h"
+#include "abc_writer_abstract.h"
+#include "abc_writer_camera.h"
+#include "abc_writer_curves.h"
+#include "abc_writer_hair.h"
+#include "abc_writer_mball.h"
+#include "abc_writer_mesh.h"
+#include "abc_writer_nurbs.h"
+#include "abc_writer_points.h"
+#include "abc_writer_transform.h"
+
+#include <memory>
+#include <string>
+
+#include "BLI_assert.h"
+
+#include "DEG_depsgraph_query.h"
+
+#include "DNA_ID.h"
+#include "DNA_layer_types.h"
+#include "DNA_object_types.h"
+
+namespace blender {
+namespace io {
+namespace alembic {
+
+ABCHierarchyIterator::ABCHierarchyIterator(Depsgraph *depsgraph,
+ ABCArchive *abc_archive,
+ const AlembicExportParams &params)
+ : AbstractHierarchyIterator(depsgraph), abc_archive_(abc_archive), params_(params)
+{
+}
+
+void ABCHierarchyIterator::iterate_and_write()
+{
+ AbstractHierarchyIterator::iterate_and_write();
+ update_archive_bounding_box();
+}
+
+void ABCHierarchyIterator::update_archive_bounding_box()
+{
+ Imath::Box3d bounds;
+ update_bounding_box_recursive(bounds, HierarchyContext::root());
+ abc_archive_->update_bounding_box(bounds);
+}
+
+void ABCHierarchyIterator::update_bounding_box_recursive(Imath::Box3d &bounds,
+ const HierarchyContext *context)
+{
+ if (context != nullptr) {
+ AbstractHierarchyWriter *abstract_writer = writers_[context->export_path];
+ ABCAbstractWriter *abc_writer = static_cast<ABCAbstractWriter *>(abstract_writer);
+
+ if (abc_writer != nullptr) {
+ bounds.extendBy(abc_writer->bounding_box());
+ }
+ }
+
+ for (HierarchyContext *child_context : graph_children(context)) {
+ update_bounding_box_recursive(bounds, child_context);
+ }
+}
+
+bool ABCHierarchyIterator::mark_as_weak_export(const Object *object) const
+{
+ if (params_.selected_only && (object->base_flag & BASE_SELECTED) == 0) {
+ return true;
+ }
+ /* TODO(Sybren): handle other flags too? */
+ return false;
+}
+
+void ABCHierarchyIterator::delete_object_writer(AbstractHierarchyWriter *writer)
+{
+ delete writer;
+}
+
+std::string ABCHierarchyIterator::make_valid_name(const std::string &name) const
+{
+ std::string abc_name(name);
+ std::replace(abc_name.begin(), abc_name.end(), ' ', '_');
+ std::replace(abc_name.begin(), abc_name.end(), '.', '_');
+ std::replace(abc_name.begin(), abc_name.end(), ':', '_');
+ return abc_name;
+}
+
+AbstractHierarchyIterator::ExportGraph::key_type ABCHierarchyIterator::
+ determine_graph_index_object(const HierarchyContext *context)
+{
+ if (params_.flatten_hierarchy) {
+ return std::make_pair(nullptr, nullptr);
+ }
+
+ return AbstractHierarchyIterator::determine_graph_index_object(context);
+}
+
+AbstractHierarchyIterator::ExportGraph::key_type ABCHierarchyIterator::determine_graph_index_dupli(
+ const HierarchyContext *context, const std::set<Object *> &dupli_set)
+{
+ if (params_.flatten_hierarchy) {
+ return std::make_pair(nullptr, nullptr);
+ }
+
+ return AbstractHierarchyIterator::determine_graph_index_dupli(context, dupli_set);
+}
+
+Alembic::Abc::OObject ABCHierarchyIterator::get_alembic_parent(
+ const HierarchyContext *context) const
+{
+ Alembic::Abc::OObject parent;
+
+ if (!context->higher_up_export_path.empty()) {
+ AbstractHierarchyWriter *writer = get_writer(context->higher_up_export_path);
+ ABCAbstractWriter *abc_writer = static_cast<ABCAbstractWriter *>(writer);
+ parent = abc_writer->get_alembic_object();
+ }
+
+ if (!parent.valid()) {
+ /* An invalid parent object means "no parent", which should be translated to Alembic's top
+ * archive object. */
+ return abc_archive_->archive->getTop();
+ }
+
+ return parent;
+}
+
+ABCWriterConstructorArgs ABCHierarchyIterator::writer_constructor_args(
+ const HierarchyContext *context) const
+{
+ ABCWriterConstructorArgs constructor_args;
+ constructor_args.depsgraph = depsgraph_;
+ constructor_args.abc_archive = abc_archive_;
+ constructor_args.abc_parent = get_alembic_parent(context);
+ constructor_args.abc_name = context->export_name;
+ constructor_args.abc_path = context->export_path;
+ constructor_args.hierarchy_iterator = this;
+ constructor_args.export_params = &params_;
+ return constructor_args;
+}
+
+AbstractHierarchyWriter *ABCHierarchyIterator::create_transform_writer(
+ const HierarchyContext *context)
+{
+ ABCAbstractWriter *transform_writer = new ABCTransformWriter(writer_constructor_args(context));
+ transform_writer->create_alembic_objects(context);
+ return transform_writer;
+}
+
+AbstractHierarchyWriter *ABCHierarchyIterator::create_data_writer(const HierarchyContext *context)
+{
+ const ABCWriterConstructorArgs writer_args = writer_constructor_args(context);
+ ABCAbstractWriter *data_writer = nullptr;
+
+ switch (context->object->type) {
+ case OB_MESH:
+ data_writer = new ABCMeshWriter(writer_args);
+ break;
+ case OB_CAMERA:
+ data_writer = new ABCCameraWriter(writer_args);
+ break;
+ case OB_CURVE:
+ if (params_.curves_as_mesh) {
+ data_writer = new ABCCurveMeshWriter(writer_args);
+ }
+ else {
+ data_writer = new ABCCurveWriter(writer_args);
+ }
+ break;
+ case OB_SURF:
+ if (params_.curves_as_mesh) {
+ data_writer = new ABCCurveMeshWriter(writer_args);
+ }
+ else {
+ data_writer = new ABCNurbsWriter(writer_args);
+ }
+ break;
+ case OB_MBALL:
+ data_writer = new ABCMetaballWriter(writer_args);
+ break;
+
+ case OB_EMPTY:
+ case OB_LAMP:
+ case OB_FONT:
+ case OB_SPEAKER:
+ case OB_LIGHTPROBE:
+ case OB_LATTICE:
+ case OB_ARMATURE:
+ case OB_GPENCIL:
+ return nullptr;
+ case OB_TYPE_MAX:
+ BLI_assert(!"OB_TYPE_MAX should not be used");
+ return nullptr;
+ }
+
+ if (!data_writer->is_supported(context)) {
+ delete data_writer;
+ return nullptr;
+ }
+
+ data_writer->create_alembic_objects(context);
+ return data_writer;
+}
+
+AbstractHierarchyWriter *ABCHierarchyIterator::create_hair_writer(const HierarchyContext *context)
+{
+ if (!params_.export_hair) {
+ return nullptr;
+ }
+
+ const ABCWriterConstructorArgs writer_args = writer_constructor_args(context);
+ ABCAbstractWriter *hair_writer = new ABCHairWriter(writer_args);
+
+ if (!hair_writer->is_supported(context)) {
+ delete hair_writer;
+ return nullptr;
+ }
+
+ hair_writer->create_alembic_objects(context);
+ return hair_writer;
+}
+
+AbstractHierarchyWriter *ABCHierarchyIterator::create_particle_writer(
+ const HierarchyContext *context)
+{
+ if (!params_.export_particles) {
+ return nullptr;
+ }
+
+ const ABCWriterConstructorArgs writer_args = writer_constructor_args(context);
+ std::unique_ptr<ABCPointsWriter> particle_writer(std::make_unique<ABCPointsWriter>(writer_args));
+
+ if (!particle_writer->is_supported(context)) {
+ return nullptr;
+ }
+
+ particle_writer->create_alembic_objects(context);
+ return particle_writer.release();
+}
+
+} // namespace alembic
+} // namespace io
+} // namespace blender