Blender  V2.93
abc_hierarchy_iterator.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2020 Blender Foundation.
17  * All rights reserved.
18  */
19 
20 #include "abc_hierarchy_iterator.h"
21 #include "abc_writer_abstract.h"
22 #include "abc_writer_camera.h"
23 #include "abc_writer_curves.h"
24 #include "abc_writer_hair.h"
25 #include "abc_writer_instance.h"
26 #include "abc_writer_mball.h"
27 #include "abc_writer_mesh.h"
28 #include "abc_writer_nurbs.h"
29 #include "abc_writer_points.h"
30 #include "abc_writer_transform.h"
31 
32 #include <memory>
33 #include <string>
34 
35 #include "BLI_assert.h"
36 
37 #include "DEG_depsgraph_query.h"
38 
39 #include "DNA_ID.h"
40 #include "DNA_layer_types.h"
41 #include "DNA_object_types.h"
42 
43 namespace blender::io::alembic {
44 
46  ABCArchive *abc_archive,
48  : AbstractHierarchyIterator(depsgraph), abc_archive_(abc_archive), params_(params)
49 {
50 }
51 
53 {
55  update_archive_bounding_box();
56 }
57 
58 void ABCHierarchyIterator::update_archive_bounding_box()
59 {
60  Imath::Box3d bounds;
61  update_bounding_box_recursive(bounds, HierarchyContext::root());
62  abc_archive_->update_bounding_box(bounds);
63 }
64 
65 void ABCHierarchyIterator::update_bounding_box_recursive(Imath::Box3d &bounds,
67 {
68  if (context != nullptr) {
69  AbstractHierarchyWriter *abstract_writer = writers_[context->export_path];
70  ABCAbstractWriter *abc_writer = static_cast<ABCAbstractWriter *>(abstract_writer);
71 
72  if (abc_writer != nullptr) {
73  bounds.extendBy(abc_writer->bounding_box());
74  }
75  }
76 
77  for (HierarchyContext *child_context : graph_children(context)) {
78  update_bounding_box_recursive(bounds, child_context);
79  }
80 }
81 
83 {
84  if (params_.selected_only && (object->base_flag & BASE_SELECTED) == 0) {
85  return true;
86  }
87  /* TODO(Sybren): handle other flags too? */
88  return false;
89 }
90 
92 {
93  delete writer;
94 }
95 
96 std::string ABCHierarchyIterator::make_valid_name(const std::string &name) const
97 {
98  std::string abc_name(name);
99  std::replace(abc_name.begin(), abc_name.end(), ' ', '_');
100  std::replace(abc_name.begin(), abc_name.end(), '.', '_');
101  std::replace(abc_name.begin(), abc_name.end(), ':', '_');
102  return abc_name;
103 }
104 
105 AbstractHierarchyIterator::ExportGraph::key_type ABCHierarchyIterator::
107 {
108  if (params_.flatten_hierarchy) {
110  }
111 
113 }
114 
115 AbstractHierarchyIterator::ExportGraph::key_type ABCHierarchyIterator::determine_graph_index_dupli(
116  const HierarchyContext *context,
117  const DupliObject *dupli_object,
118  const DupliParentFinder &dupli_parent_finder)
119 {
120  if (params_.flatten_hierarchy) {
122  }
123 
125  context, dupli_object, dupli_parent_finder);
126 }
127 
129  const std::string &export_path) const
130 {
131  if (export_path.empty()) {
132  return Alembic::Abc::OObject();
133  }
134 
135  AbstractHierarchyWriter *writer = get_writer(export_path);
136  if (writer == nullptr) {
137  return Alembic::Abc::OObject();
138  }
139 
140  ABCAbstractWriter *abc_writer = static_cast<ABCAbstractWriter *>(writer);
141  return abc_writer->get_alembic_object();
142 }
143 
144 Alembic::Abc::OObject ABCHierarchyIterator::get_alembic_parent(
145  const HierarchyContext *context) const
146 {
147  Alembic::Abc::OObject parent = get_alembic_object(context->higher_up_export_path);
148 
149  if (!parent.valid()) {
150  /* An invalid parent object means "no parent", which should be translated to Alembic's top
151  * archive object. */
152  return abc_archive_->archive->getTop();
153  }
154 
155  return parent;
156 }
157 
158 ABCWriterConstructorArgs ABCHierarchyIterator::writer_constructor_args(
159  const HierarchyContext *context) const
160 {
161  ABCWriterConstructorArgs constructor_args;
162  constructor_args.depsgraph = depsgraph_;
163  constructor_args.abc_archive = abc_archive_;
164  constructor_args.abc_parent = get_alembic_parent(context);
165  constructor_args.abc_name = context->export_name;
166  constructor_args.abc_path = context->export_path;
167  constructor_args.hierarchy_iterator = this;
168  constructor_args.export_params = &params_;
169  return constructor_args;
170 }
171 
173  const HierarchyContext *context)
174 {
175  ABCAbstractWriter *transform_writer = new ABCTransformWriter(writer_constructor_args(context));
176  transform_writer->create_alembic_objects(context);
177  return transform_writer;
178 }
179 
181 {
182  const ABCWriterConstructorArgs writer_args = writer_constructor_args(context);
183  ABCAbstractWriter *data_writer = nullptr;
184 
185  if (params_.use_instancing && context->is_instance()) {
186  data_writer = new ABCInstanceWriter(writer_args);
187  }
188  else {
189  data_writer = create_data_writer_for_object_type(context, writer_args);
190  }
191 
192  if (data_writer == nullptr || !data_writer->is_supported(context)) {
193  delete data_writer;
194  return nullptr;
195  }
196 
197  data_writer->create_alembic_objects(context);
198  return data_writer;
199 }
200 
201 ABCAbstractWriter *ABCHierarchyIterator::create_data_writer_for_object_type(
202  const HierarchyContext *context, const ABCWriterConstructorArgs &writer_args)
203 {
204  switch (context->object->type) {
205  case OB_MESH:
206  return new ABCMeshWriter(writer_args);
207  case OB_CAMERA:
208  return new ABCCameraWriter(writer_args);
209  case OB_CURVE:
210  if (params_.curves_as_mesh) {
211  return new ABCCurveMeshWriter(writer_args);
212  }
213  return new ABCCurveWriter(writer_args);
214  case OB_SURF:
215  if (params_.curves_as_mesh) {
216  return new ABCCurveMeshWriter(writer_args);
217  }
218  return new ABCNurbsWriter(writer_args);
219  case OB_MBALL:
220  return new ABCMetaballWriter(writer_args);
221 
222  case OB_EMPTY:
223  case OB_LAMP:
224  case OB_FONT:
225  case OB_SPEAKER:
226  case OB_LIGHTPROBE:
227  case OB_LATTICE:
228  case OB_ARMATURE:
229  case OB_GPENCIL:
230  return nullptr;
231  case OB_TYPE_MAX:
232  BLI_assert(!"OB_TYPE_MAX should not be used");
233  return nullptr;
234  }
235 
236  /* Just to please the compiler, all cases should be handled by the above switch. */
237  return nullptr;
238 }
239 
241 {
242  if (!params_.export_hair) {
243  return nullptr;
244  }
245 
246  const ABCWriterConstructorArgs writer_args = writer_constructor_args(context);
247  ABCAbstractWriter *hair_writer = new ABCHairWriter(writer_args);
248 
249  if (!hair_writer->is_supported(context)) {
250  delete hair_writer;
251  return nullptr;
252  }
253 
254  hair_writer->create_alembic_objects(context);
255  return hair_writer;
256 }
257 
259  const HierarchyContext *context)
260 {
261  if (!params_.export_particles) {
262  return nullptr;
263  }
264 
265  const ABCWriterConstructorArgs writer_args = writer_constructor_args(context);
266  std::unique_ptr<ABCPointsWriter> particle_writer(std::make_unique<ABCPointsWriter>(writer_args));
267 
268  if (!particle_writer->is_supported(context)) {
269  return nullptr;
270  }
271 
272  particle_writer->create_alembic_objects(context);
273  return particle_writer.release();
274 }
275 
276 } // namespace blender::io::alembic
#define BLI_assert(a)
Definition: BLI_assert.h:58
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
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_CURVE
@ 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:49
void update_bounding_box(const Imath::Box3d &bounds)
Definition: abc_archive.cc:256
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(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]
struct SELECTID_Context context
Definition: select_engine.c:47
short base_flag
static const HierarchyContext * root()