Blender V5.0
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#include "intern/abc_util.h"
17
18#include <memory>
19#include <string>
20
21#include "BLI_assert.h"
22
23#include "DNA_layer_types.h"
24#include "DNA_object_types.h"
25
26namespace blender::io::alembic {
27
29 Depsgraph *depsgraph,
30 ABCArchive *abc_archive,
32 : AbstractHierarchyIterator(bmain, depsgraph), abc_archive_(abc_archive), params_(params)
33{
34}
35
41
42void ABCHierarchyIterator::update_archive_bounding_box()
43{
44 Imath::Box3d bounds;
45 update_bounding_box_recursive(bounds, HierarchyContext::root());
46 abc_archive_->update_bounding_box(bounds);
47}
48
49void ABCHierarchyIterator::update_bounding_box_recursive(Imath::Box3d &bounds,
50 const HierarchyContext *context)
51{
52 if (context != nullptr) {
53 AbstractHierarchyWriter *abstract_writer = writers_.lookup(context->export_path);
54 ABCAbstractWriter *abc_writer = static_cast<ABCAbstractWriter *>(abstract_writer);
55
56 if (abc_writer != nullptr) {
57 bounds.extendBy(abc_writer->bounding_box());
58 }
59 }
60
61 ExportChildren *children = graph_children(context);
62 if (!children) {
63 return;
64 }
65
66 for (HierarchyContext *child_context : *children) {
67 update_bounding_box_recursive(bounds, child_context);
68 }
69}
70
72{
73 if (params_.selected_only && (object->base_flag & BASE_SELECTED) == 0) {
74 return true;
75 }
76 /* TODO(Sybren): handle other flags too? */
77 return false;
78}
79
81{
82 delete writer;
83}
84
85std::string ABCHierarchyIterator::make_valid_name(const std::string &name) const
86{
87 return get_valid_abc_name(name.c_str());
88}
89
99
101 const HierarchyContext *context,
102 const DupliObject *dupli_object,
103 const DupliParentFinder &dupli_parent_finder)
104{
105 if (params_.flatten_hierarchy) {
107 }
108
110 context, dupli_object, dupli_parent_finder);
111}
112
114 const std::string &export_path) const
115{
116 if (export_path.empty()) {
117 return Alembic::Abc::OObject();
118 }
119
120 AbstractHierarchyWriter *writer = get_writer(export_path);
121 if (writer == nullptr) {
122 return Alembic::Abc::OObject();
123 }
124
125 ABCAbstractWriter *abc_writer = static_cast<ABCAbstractWriter *>(writer);
126 return abc_writer->get_alembic_object();
127}
128
129Alembic::Abc::OObject ABCHierarchyIterator::get_alembic_parent(
130 const HierarchyContext *context) const
131{
132 Alembic::Abc::OObject parent = get_alembic_object(context->higher_up_export_path);
133
134 if (!parent.valid()) {
135 /* An invalid parent object means "no parent", which should be translated to Alembic's top
136 * archive object. */
137 return abc_archive_->archive->getTop();
138 }
139
140 return parent;
141}
142
143ABCWriterConstructorArgs ABCHierarchyIterator::writer_constructor_args(
144 const HierarchyContext *context) const
145{
146 ABCWriterConstructorArgs constructor_args;
147 constructor_args.depsgraph = depsgraph_;
148 constructor_args.abc_archive = abc_archive_;
149 constructor_args.abc_parent = get_alembic_parent(context);
150 constructor_args.abc_name = context->export_name;
151 constructor_args.abc_path = context->export_path;
152 constructor_args.hierarchy_iterator = this;
153 constructor_args.export_params = &params_;
154 return constructor_args;
155}
156
158 const HierarchyContext *context)
159{
160 ABCAbstractWriter *transform_writer = new ABCTransformWriter(writer_constructor_args(context));
161 transform_writer->create_alembic_objects(context);
162 return transform_writer;
163}
164
166{
167 const ABCWriterConstructorArgs writer_args = writer_constructor_args(context);
168 ABCAbstractWriter *data_writer = nullptr;
169
170 if (params_.use_instancing && context->is_instance()) {
171 data_writer = new ABCInstanceWriter(writer_args);
172 }
173 else {
174 data_writer = create_data_writer_for_object_type(context, writer_args);
175 }
176
177 if (data_writer == nullptr || !data_writer->is_supported(context)) {
178 delete data_writer;
179 return nullptr;
180 }
181
182 data_writer->create_alembic_objects(context);
183 return data_writer;
184}
185
186ABCAbstractWriter *ABCHierarchyIterator::create_data_writer_for_object_type(
187 const HierarchyContext *context, const ABCWriterConstructorArgs &writer_args)
188{
189 switch (context->object->type) {
190 case OB_MESH:
191 return new ABCMeshWriter(writer_args);
192 case OB_CAMERA:
193 return new ABCCameraWriter(writer_args);
194 case OB_CURVES_LEGACY:
195 case OB_CURVES:
196 if (params_.curves_as_mesh) {
197 return new ABCCurveMeshWriter(writer_args);
198 }
199 return new ABCCurveWriter(writer_args);
200 case OB_SURF:
201 if (params_.curves_as_mesh) {
202 return new ABCCurveMeshWriter(writer_args);
203 }
204 return new ABCNurbsWriter(writer_args);
205 case OB_MBALL:
206 return new ABCMetaballWriter(writer_args);
207
208 case OB_EMPTY:
209 case OB_LAMP:
210 case OB_FONT:
211 case OB_SPEAKER:
212 case OB_LIGHTPROBE:
213 case OB_LATTICE:
214 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:53
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_CURVES
@ OB_LIGHTPROBE
#define BASE_SELECTED(v3d, base)
BPy_StructRNA * depsgraph
const Value & lookup(const Key &key) const
Definition BLI_map.hh:545
virtual ObjectIdentifier determine_graph_index_object(const HierarchyContext *context)
ExportChildren * graph_children(const HierarchyContext *context)
AbstractHierarchyIterator(Main *bmain, Depsgraph *depsgraph)
virtual ObjectIdentifier determine_graph_index_dupli(const HierarchyContext *context, const DupliObject *dupli_object, const DupliParentFinder &dupli_parent_finder)
AbstractHierarchyWriter * get_writer(const std::string &export_path) const
blender::Set< HierarchyContext * > ExportChildren
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)
bool mark_as_weak_export(const Object *object) const override
AbstractHierarchyWriter * create_particle_writer(const HierarchyContext *context) override
Alembic::Abc::OObject get_alembic_object(const std::string &export_path) const
AbstractHierarchyWriter * create_hair_writer(const HierarchyContext *context) override
ObjectIdentifier determine_graph_index_dupli(const HierarchyContext *context, const DupliObject *dupli_object, const DupliParentFinder &dupli_parent_finder) override
std::string make_valid_name(const std::string &name) const override
AbstractHierarchyWriter * create_data_writer(const HierarchyContext *context) override
ObjectIdentifier determine_graph_index_object(const HierarchyContext *context) override
AbstractHierarchyWriter * create_transform_writer(const HierarchyContext *context) override
void release_writer(AbstractHierarchyWriter *writer) override
ABCHierarchyIterator(Main *bmain, Depsgraph *depsgraph, ABCArchive *abc_archive, const AlembicExportParams &params)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
std::string get_valid_abc_name(const char *name)
Definition abc_util.cc:29
const char * name
short base_flag
static const HierarchyContext * root()