Blender V4.3
abc_hierarchy_iterator.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
7#include "abc_writer_camera.h"
8#include "abc_writer_curves.h"
9#include "abc_writer_hair.h"
10#include "abc_writer_instance.h"
11#include "abc_writer_mball.h"
12#include "abc_writer_mesh.h"
13#include "abc_writer_nurbs.h"
14#include "abc_writer_points.h"
16
17#include <memory>
18#include <string>
19
20#include "BLI_assert.h"
21
22#include "DNA_layer_types.h"
23#include "DNA_object_types.h"
24
25namespace blender::io::alembic {
26
28 Depsgraph *depsgraph,
29 ABCArchive *abc_archive,
31 : AbstractHierarchyIterator(bmain, depsgraph), abc_archive_(abc_archive), params_(params)
32{
33}
34
40
41void ABCHierarchyIterator::update_archive_bounding_box()
42{
43 Imath::Box3d bounds;
44 update_bounding_box_recursive(bounds, HierarchyContext::root());
45 abc_archive_->update_bounding_box(bounds);
46}
47
48void ABCHierarchyIterator::update_bounding_box_recursive(Imath::Box3d &bounds,
49 const HierarchyContext *context)
50{
51 if (context != nullptr) {
52 AbstractHierarchyWriter *abstract_writer = writers_[context->export_path];
53 ABCAbstractWriter *abc_writer = static_cast<ABCAbstractWriter *>(abstract_writer);
54
55 if (abc_writer != nullptr) {
56 bounds.extendBy(abc_writer->bounding_box());
57 }
58 }
59
60 for (HierarchyContext *child_context : graph_children(context)) {
61 update_bounding_box_recursive(bounds, child_context);
62 }
63}
64
66{
67 if (params_.selected_only && (object->base_flag & BASE_SELECTED) == 0) {
68 return true;
69 }
70 /* TODO(Sybren): handle other flags too? */
71 return false;
72}
73
75{
76 delete writer;
77}
78
79std::string ABCHierarchyIterator::make_valid_name(const std::string &name) const
80{
81 std::string abc_name(name);
82 std::replace(abc_name.begin(), abc_name.end(), ' ', '_');
83 std::replace(abc_name.begin(), abc_name.end(), '.', '_');
84 std::replace(abc_name.begin(), abc_name.end(), ':', '_');
85 std::replace(abc_name.begin(), abc_name.end(), '/', '_');
86 return abc_name;
87}
88
89AbstractHierarchyIterator::ExportGraph::key_type ABCHierarchyIterator::
91{
92 if (params_.flatten_hierarchy) {
94 }
95
97}
98
99AbstractHierarchyIterator::ExportGraph::key_type ABCHierarchyIterator::determine_graph_index_dupli(
100 const HierarchyContext *context,
101 const DupliObject *dupli_object,
102 const DupliParentFinder &dupli_parent_finder)
103{
104 if (params_.flatten_hierarchy) {
106 }
107
109 context, dupli_object, dupli_parent_finder);
110}
111
113 const std::string &export_path) const
114{
115 if (export_path.empty()) {
116 return Alembic::Abc::OObject();
117 }
118
119 AbstractHierarchyWriter *writer = get_writer(export_path);
120 if (writer == nullptr) {
121 return Alembic::Abc::OObject();
122 }
123
124 ABCAbstractWriter *abc_writer = static_cast<ABCAbstractWriter *>(writer);
125 return abc_writer->get_alembic_object();
126}
127
128Alembic::Abc::OObject ABCHierarchyIterator::get_alembic_parent(
129 const HierarchyContext *context) const
130{
131 Alembic::Abc::OObject parent = get_alembic_object(context->higher_up_export_path);
132
133 if (!parent.valid()) {
134 /* An invalid parent object means "no parent", which should be translated to Alembic's top
135 * archive object. */
136 return abc_archive_->archive->getTop();
137 }
138
139 return parent;
140}
141
142ABCWriterConstructorArgs ABCHierarchyIterator::writer_constructor_args(
143 const HierarchyContext *context) const
144{
145 ABCWriterConstructorArgs constructor_args;
146 constructor_args.depsgraph = depsgraph_;
147 constructor_args.abc_archive = abc_archive_;
148 constructor_args.abc_parent = get_alembic_parent(context);
149 constructor_args.abc_name = context->export_name;
150 constructor_args.abc_path = context->export_path;
151 constructor_args.hierarchy_iterator = this;
152 constructor_args.export_params = &params_;
153 return constructor_args;
154}
155
157 const HierarchyContext *context)
158{
159 ABCAbstractWriter *transform_writer = new ABCTransformWriter(writer_constructor_args(context));
160 transform_writer->create_alembic_objects(context);
161 return transform_writer;
162}
163
165{
166 const ABCWriterConstructorArgs writer_args = writer_constructor_args(context);
167 ABCAbstractWriter *data_writer = nullptr;
168
169 if (params_.use_instancing && context->is_instance()) {
170 data_writer = new ABCInstanceWriter(writer_args);
171 }
172 else {
173 data_writer = create_data_writer_for_object_type(context, writer_args);
174 }
175
176 if (data_writer == nullptr || !data_writer->is_supported(context)) {
177 delete data_writer;
178 return nullptr;
179 }
180
181 data_writer->create_alembic_objects(context);
182 return data_writer;
183}
184
185ABCAbstractWriter *ABCHierarchyIterator::create_data_writer_for_object_type(
186 const HierarchyContext *context, const ABCWriterConstructorArgs &writer_args)
187{
188 switch (context->object->type) {
189 case OB_MESH:
190 return new ABCMeshWriter(writer_args);
191 case OB_CAMERA:
192 return new ABCCameraWriter(writer_args);
193 case OB_CURVES_LEGACY:
194 case OB_CURVES:
195 if (params_.curves_as_mesh) {
196 return new ABCCurveMeshWriter(writer_args);
197 }
198 return new ABCCurveWriter(writer_args);
199 case OB_SURF:
200 if (params_.curves_as_mesh) {
201 return new ABCCurveMeshWriter(writer_args);
202 }
203 return new ABCNurbsWriter(writer_args);
204 case OB_MBALL:
205 return new ABCMetaballWriter(writer_args);
206
207 case OB_EMPTY:
208 case OB_LAMP:
209 case OB_FONT:
210 case OB_SPEAKER:
211 case OB_LIGHTPROBE:
212 case OB_LATTICE:
213 case OB_ARMATURE:
215 return nullptr;
216 case OB_TYPE_MAX:
217 BLI_assert_msg(0, "OB_TYPE_MAX should not be used");
218 return nullptr;
219 }
220
221 /* Just to please the compiler, all cases should be handled by the above switch. */
222 return nullptr;
223}
224
226{
227 if (!params_.export_hair) {
228 return nullptr;
229 }
230
231 const ABCWriterConstructorArgs writer_args = writer_constructor_args(context);
232 ABCAbstractWriter *hair_writer = new ABCHairWriter(writer_args);
233
234 if (!hair_writer->is_supported(context)) {
235 delete hair_writer;
236 return nullptr;
237 }
238
239 hair_writer->create_alembic_objects(context);
240 return hair_writer;
241}
242
244 const HierarchyContext *context)
245{
246 if (!params_.export_particles) {
247 return nullptr;
248 }
249
250 const ABCWriterConstructorArgs writer_args = writer_constructor_args(context);
251 std::unique_ptr<ABCPointsWriter> particle_writer(std::make_unique<ABCPointsWriter>(writer_args));
252
253 if (!particle_writer->is_supported(context)) {
254 return nullptr;
255 }
256
257 particle_writer->create_alembic_objects(context);
258 return particle_writer.release();
259}
260
261} // namespace blender::io::alembic
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
Object is a sort of wrapper for general info.
@ OB_SPEAKER
@ OB_LATTICE
@ OB_MBALL
@ OB_EMPTY
@ OB_SURF
@ OB_CAMERA
@ OB_FONT
@ OB_TYPE_MAX
@ OB_ARMATURE
@ OB_LAMP
@ OB_MESH
@ OB_CURVES_LEGACY
@ OB_GPENCIL_LEGACY
@ OB_CURVES
@ OB_LIGHTPROBE
#define BASE_SELECTED(v3d, base)
virtual ExportGraph::key_type determine_graph_index_object(const HierarchyContext *context)
ExportChildren & graph_children(const HierarchyContext *context)
AbstractHierarchyWriter * get_writer(const std::string &export_path) const
virtual ExportGraph::key_type determine_graph_index_dupli(const HierarchyContext *context, const DupliObject *dupli_object, const DupliParentFinder &dupli_parent_finder)
static ObjectIdentifier for_graph_root()
virtual void create_alembic_objects(const HierarchyContext *context)=0
virtual bool is_supported(const HierarchyContext *context) const
virtual Alembic::Abc::OObject get_alembic_object() const =0
Alembic::Abc::OArchive * archive
Definition abc_archive.h:34
void update_bounding_box(const Imath::Box3d &bounds)
virtual bool mark_as_weak_export(const Object *object) const override
virtual AbstractHierarchyWriter * create_particle_writer(const HierarchyContext *context) override
Alembic::Abc::OObject get_alembic_object(const std::string &export_path) const
virtual AbstractHierarchyWriter * create_hair_writer(const HierarchyContext *context) override
virtual std::string make_valid_name(const std::string &name) const override
virtual AbstractHierarchyWriter * create_data_writer(const HierarchyContext *context) override
virtual AbstractHierarchyWriter * create_transform_writer(const HierarchyContext *context) override
virtual AbstractHierarchyIterator::ExportGraph::key_type determine_graph_index_dupli(const HierarchyContext *context, const DupliObject *dupli_object, const DupliParentFinder &dupli_parent_finder) override
virtual void release_writer(AbstractHierarchyWriter *writer) override
ABCHierarchyIterator(Main *bmain, Depsgraph *depsgraph, ABCArchive *abc_archive, const AlembicExportParams &params)
virtual ExportGraph::key_type determine_graph_index_object(const HierarchyContext *context) override
const Depsgraph * depsgraph
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
static const HierarchyContext * root()