Blender  V3.3
abc_hierarchy_iterator.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2020 Blender Foundation. All rights reserved. */
3 
5 #include "abc_writer_abstract.h"
6 #include "abc_writer_camera.h"
7 #include "abc_writer_curves.h"
8 #include "abc_writer_hair.h"
9 #include "abc_writer_instance.h"
10 #include "abc_writer_mball.h"
11 #include "abc_writer_mesh.h"
12 #include "abc_writer_nurbs.h"
13 #include "abc_writer_points.h"
14 #include "abc_writer_transform.h"
15 
16 #include <memory>
17 #include <string>
18 
19 #include "BLI_assert.h"
20 
21 #include "DEG_depsgraph_query.h"
22 
23 #include "DNA_ID.h"
24 #include "DNA_layer_types.h"
25 #include "DNA_object_types.h"
26 
27 namespace blender::io::alembic {
28 
31  ABCArchive *abc_archive,
33  : AbstractHierarchyIterator(bmain, depsgraph), abc_archive_(abc_archive), params_(params)
34 {
35 }
36 
38 {
40  update_archive_bounding_box();
41 }
42 
43 void ABCHierarchyIterator::update_archive_bounding_box()
44 {
45  Imath::Box3d bounds;
46  update_bounding_box_recursive(bounds, HierarchyContext::root());
47  abc_archive_->update_bounding_box(bounds);
48 }
49 
50 void ABCHierarchyIterator::update_bounding_box_recursive(Imath::Box3d &bounds,
52 {
53  if (context != nullptr) {
54  AbstractHierarchyWriter *abstract_writer = writers_[context->export_path];
55  ABCAbstractWriter *abc_writer = static_cast<ABCAbstractWriter *>(abstract_writer);
56 
57  if (abc_writer != nullptr) {
58  bounds.extendBy(abc_writer->bounding_box());
59  }
60  }
61 
62  for (HierarchyContext *child_context : graph_children(context)) {
63  update_bounding_box_recursive(bounds, child_context);
64  }
65 }
66 
68 {
69  if (params_.selected_only && (object->base_flag & BASE_SELECTED) == 0) {
70  return true;
71  }
72  /* TODO(Sybren): handle other flags too? */
73  return false;
74 }
75 
77 {
78  delete writer;
79 }
80 
81 std::string ABCHierarchyIterator::make_valid_name(const std::string &name) const
82 {
83  std::string abc_name(name);
84  std::replace(abc_name.begin(), abc_name.end(), ' ', '_');
85  std::replace(abc_name.begin(), abc_name.end(), '.', '_');
86  std::replace(abc_name.begin(), abc_name.end(), ':', '_');
87  return abc_name;
88 }
89 
90 AbstractHierarchyIterator::ExportGraph::key_type ABCHierarchyIterator::
92 {
93  if (params_.flatten_hierarchy) {
95  }
96 
98 }
99 
100 AbstractHierarchyIterator::ExportGraph::key_type ABCHierarchyIterator::determine_graph_index_dupli(
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 
129 Alembic::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 
143 ABCWriterConstructorArgs 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 
186 ABCAbstractWriter *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  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:
214  case OB_GPENCIL:
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
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
ID and Library types, which are fundamental for sdna.
@ BASE_SELECTED
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
@ OB_LIGHTPROBE
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition: btDbvt.cpp:299
virtual ExportGraph::key_type determine_graph_index_object(const HierarchyContext *context)
ExportChildren & graph_children(const HierarchyContext *parent_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:33
void update_bounding_box(const Imath::Box3d &bounds)
Definition: abc_archive.cc:240
virtual bool mark_as_weak_export(const Object *object) const override
virtual AbstractHierarchyWriter * create_particle_writer(const HierarchyContext *context) override
ABCHierarchyIterator(Main *bmain, Depsgraph *depsgraph, ABCArchive *abc_archive_, const AlembicExportParams &params)
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
virtual ExportGraph::key_type determine_graph_index_object(const HierarchyContext *context) override
const Depsgraph * depsgraph
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
Definition: BKE_main.h:121
short base_flag
static const HierarchyContext * root()