2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software Foundation,
16 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * Contributor(s): Esteban Tovagliari, Cedric Paille, Kevin Dietrich
20 * ***** END GPL LICENSE BLOCK *****
23 #include "abc_exporter.h"
27 #include "abc_archive.h"
28 #include "abc_camera.h"
29 #include "abc_curves.h"
32 #include "abc_nurbs.h"
33 #include "abc_points.h"
34 #include "abc_transform.h"
38 #include "DNA_camera_types.h"
39 #include "DNA_curve_types.h"
40 #include "DNA_mesh_types.h"
41 #include "DNA_modifier_types.h"
42 #include "DNA_object_types.h"
43 #include "DNA_scene_types.h"
44 #include "DNA_space_types.h" /* for FILE_MAX */
46 #include "BLI_string.h"
49 /* needed for MSCV because of snprintf from BLI_string */
50 # include "BLI_winstuff.h"
54 #include "BKE_global.h"
55 #include "BKE_idprop.h"
57 #include "BKE_modifier.h"
58 #include "BKE_particle.h"
59 #include "BKE_scene.h"
62 using Alembic::Abc::TimeSamplingPtr;
63 using Alembic::Abc::OBox3dProperty;
65 /* ************************************************************************** */
67 ExportSettings::ExportSettings()
70 , selected_only(false)
71 , visible_layers_only(false)
72 , renderable_only(false)
80 , flatten_hierarchy(false)
81 , export_normals(false)
84 , export_face_sets(false)
85 , export_vweigths(false)
87 , export_particles(true)
89 , use_subdiv_schema(false)
90 , export_child_hairs(true)
96 , do_convert_axis(false)
99 static bool object_is_smoke_sim(Object *ob)
101 ModifierData *md = modifiers_findByType(ob, eModifierType_Smoke);
104 SmokeModifierData *smd = reinterpret_cast<SmokeModifierData *>(md);
105 return (smd->type == MOD_SMOKE_TYPE_DOMAIN);
111 static bool object_is_shape(Object *ob)
115 if (object_is_smoke_sim(ob)) {
131 * Returns whether this object should be exported into the Alembic file.
133 * @param settings export settings, used for options like 'selected only'.
134 * @param ob the object in question.
135 * @param is_duplicated normally false; true when the object is instanced
136 * into the scene by a dupli-object (e.g. part of a
137 * dupligroup). This ignores selection and layer
138 * visibility, and assumes that the dupli-object itself
139 * (e.g. the group-instantiating empty) is exported.
141 static bool export_object(const ExportSettings * const settings, Object *ob,
144 if (!is_duplicated) {
145 /* These two tests only make sense when the object isn't being instanced
146 * into the scene. When it is, its exportability is determined by
147 * its dupli-object and the DupliObject::no_draw property. */
148 if (settings->selected_only && !parent_selected(ob)) {
152 if (settings->visible_layers_only && !(settings->scene->lay & ob->lay)) {
157 if (settings->renderable_only && (ob->restrictflag & OB_RESTRICT_RENDER)) {
164 /* ************************************************************************** */
166 AbcExporter::AbcExporter(Scene *scene, const char *filename, ExportSettings &settings)
167 : m_settings(settings)
168 , m_filename(filename)
169 , m_trans_sampling_index(0)
170 , m_shape_sampling_index(0)
175 AbcExporter::~AbcExporter()
177 /* Free xforms map */
178 m_xforms_type::iterator it_x, e_x;
179 for (it_x = m_xforms.begin(), e_x = m_xforms.end(); it_x != e_x; ++it_x) {
183 /* Free shapes vector */
184 for (int i = 0, e = m_shapes.size(); i != e; ++i) {
191 void AbcExporter::getShutterSamples(double step, bool time_relative,
192 std::vector<double> &samples)
196 const double time_factor = time_relative ? m_scene->r.frs_sec : 1.0;
197 const double shutter_open = m_settings.shutter_open;
198 const double shutter_close = m_settings.shutter_close;
200 /* sample all frame */
201 if (shutter_open == 0.0 && shutter_close == 1.0) {
202 for (double t = 0.0; t < 1.0; t += step) {
203 samples.push_back((t + m_settings.frame_start) / time_factor);
207 /* sample between shutter open & close */
208 const int nsamples = static_cast<int>(std::max((1.0 / step) - 1.0, 1.0));
209 const double time_inc = (shutter_close - shutter_open) / nsamples;
211 for (double t = shutter_open; t <= shutter_close; t += time_inc) {
212 samples.push_back((t + m_settings.frame_start) / time_factor);
217 Alembic::Abc::TimeSamplingPtr AbcExporter::createTimeSampling(double step)
219 TimeSamplingPtr time_sampling;
220 std::vector<double> samples;
222 if (m_settings.frame_start == m_settings.frame_end) {
223 time_sampling.reset(new Alembic::Abc::TimeSampling());
224 return time_sampling;
227 getShutterSamples(step, true, samples);
229 Alembic::Abc::TimeSamplingType ts(static_cast<uint32_t>(samples.size()), 1.0 / m_scene->r.frs_sec);
230 time_sampling.reset(new Alembic::Abc::TimeSampling(ts, samples));
232 return time_sampling;
235 void AbcExporter::getFrameSet(double step, std::set<double> &frames)
239 std::vector<double> shutter_samples;
241 getShutterSamples(step, false, shutter_samples);
243 for (double frame = m_settings.frame_start; frame <= m_settings.frame_end; frame += 1.0) {
244 for (int j = 0, e = shutter_samples.size(); j < e; ++j) {
245 frames.insert(frame + shutter_samples[j]);
250 void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled)
252 std::string scene_name;
254 if (bmain->name[0] != '\0') {
255 char scene_file_name[FILE_MAX];
256 BLI_strncpy(scene_file_name, bmain->name, FILE_MAX);
257 scene_name = scene_file_name;
260 scene_name = "untitled";
263 Scene *scene = m_scene;
264 const double fps = FPS;
266 snprintf(buf, 15, "%f", fps);
267 const std::string str_fps = buf;
269 Alembic::AbcCoreAbstract::MetaData md;
270 md.set("FramesPerTimeUnit", str_fps);
272 m_writer = new ArchiveWriter(m_filename, scene_name.c_str(), m_settings.export_ogawa, md);
274 /* Create time samplings for transforms and shapes. */
276 TimeSamplingPtr trans_time = createTimeSampling(m_settings.frame_step_xform);
278 m_trans_sampling_index = m_writer->archive().addTimeSampling(*trans_time);
280 TimeSamplingPtr shape_time;
282 if ((m_settings.frame_step_shape == m_settings.frame_step_xform) ||
283 (m_settings.frame_start == m_settings.frame_end))
285 shape_time = trans_time;
286 m_shape_sampling_index = m_trans_sampling_index;
289 shape_time = createTimeSampling(m_settings.frame_step_shape);
290 m_shape_sampling_index = m_writer->archive().addTimeSampling(*shape_time);
293 OBox3dProperty archive_bounds_prop = Alembic::AbcGeom::CreateOArchiveBounds(m_writer->archive(), m_trans_sampling_index);
295 createTransformWritersHierarchy(bmain->eval_ctx);
296 createShapeWriters(bmain->eval_ctx);
298 /* Make a list of frames to export. */
300 std::set<double> xform_frames;
301 getFrameSet(m_settings.frame_step_xform, xform_frames);
303 std::set<double> shape_frames;
304 getFrameSet(m_settings.frame_step_shape, shape_frames);
306 /* Merge all frames needed. */
308 std::set<double> frames(xform_frames);
309 frames.insert(shape_frames.begin(), shape_frames.end());
311 /* Export all frames. */
313 std::set<double>::const_iterator begin = frames.begin();
314 std::set<double>::const_iterator end = frames.end();
316 const float size = static_cast<float>(frames.size());
319 for (; begin != end; ++begin) {
320 progress = (++i / size);
327 const double frame = *begin;
329 /* 'frame' is offset by start frame, so need to cancel the offset. */
330 setCurrentFrame(bmain, frame - m_settings.frame_start);
332 if (shape_frames.count(frame) != 0) {
333 for (int i = 0, e = m_shapes.size(); i != e; ++i) {
334 m_shapes[i]->write();
338 if (xform_frames.count(frame) == 0) {
342 m_xforms_type::iterator xit, xe;
343 for (xit = m_xforms.begin(), xe = m_xforms.end(); xit != xe; ++xit) {
344 xit->second->write();
347 /* Save the archive 's bounding box. */
350 for (xit = m_xforms.begin(), xe = m_xforms.end(); xit != xe; ++xit) {
351 Imath::Box3d box = xit->second->bounds();
352 bounds.extendBy(box);
355 archive_bounds_prop.set(bounds);
359 void AbcExporter::createTransformWritersHierarchy(EvaluationContext *eval_ctx)
361 Base *base = static_cast<Base *>(m_scene->base.first);
364 Object *ob = base->object;
371 /* We do not export transforms for objects of these classes. */
375 exploreTransform(eval_ctx, ob, ob->parent);
382 void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Object *ob, Object *parent, Object *dupliObParent)
384 /* If an object isn't exported itself, its duplilist shouldn't be
385 * exported either. */
386 if (!export_object(&m_settings, ob, dupliObParent != NULL)) {
390 if (object_is_shape(ob)) {
391 createTransformWriter(ob, parent, dupliObParent);
394 ListBase *lb = object_duplilist(eval_ctx, m_scene, ob);
397 DupliObject *link = static_cast<DupliObject *>(lb->first);
398 Object *dupli_ob = NULL;
399 Object *dupli_parent = NULL;
401 for (; link; link = link->next) {
402 /* This skips things like custom bone shapes. */
403 if (m_settings.renderable_only && link->no_draw) {
407 if (link->type == OB_DUPLIGROUP) {
409 dupli_parent = (dupli_ob->parent) ? dupli_ob->parent : ob;
411 exploreTransform(eval_ctx, dupli_ob, dupli_parent, ob);
416 free_object_duplilist(lb);
419 AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *parent, Object *dupliObParent)
421 /* An object should not be its own parent, or we'll get infinite loops. */
422 BLI_assert(ob != parent);
423 BLI_assert(ob != dupliObParent);
426 if (m_settings.flatten_hierarchy) {
427 name = get_id_name(ob);
430 name = get_object_dag_path_name(ob, dupliObParent);
433 /* check if we have already created a transform writer for this object */
434 AbcTransformWriter *my_writer = getXForm(name);
435 if (my_writer != NULL){
439 AbcTransformWriter *parent_writer = NULL;
440 Alembic::Abc::OObject alembic_parent;
442 if (m_settings.flatten_hierarchy || parent == NULL) {
443 /* Parentless objects still have the "top object" as parent
445 alembic_parent = m_writer->archive().getTop();
448 /* Since there are so many different ways to find parents (as evident
449 * in the number of conditions below), we can't really look up the
450 * parent by name. We'll just call createTransformWriter(), which will
451 * return the parent's AbcTransformWriter pointer. */
452 if (parent->parent) {
453 if (parent == dupliObParent) {
454 parent_writer = createTransformWriter(parent, parent->parent, NULL);
457 parent_writer = createTransformWriter(parent, parent->parent, dupliObParent);
460 else if (parent == dupliObParent) {
461 if (dupliObParent->parent == NULL) {
462 parent_writer = createTransformWriter(parent, NULL, NULL);
465 parent_writer = createTransformWriter(parent, dupliObParent->parent, dupliObParent->parent);
469 parent_writer = createTransformWriter(parent, dupliObParent, dupliObParent);
472 BLI_assert(parent_writer);
473 alembic_parent = parent_writer->alembicXform();
476 my_writer = new AbcTransformWriter(ob, alembic_parent, parent_writer,
477 m_trans_sampling_index, m_settings);
479 /* When flattening, the matrix of the dupliobject has to be added. */
480 if (m_settings.flatten_hierarchy && dupliObParent) {
481 my_writer->m_proxy_from = dupliObParent;
484 m_xforms[name] = my_writer;
488 void AbcExporter::createShapeWriters(EvaluationContext *eval_ctx)
490 Base *base = static_cast<Base *>(m_scene->base.first);
493 Object *ob = base->object;
494 exploreObject(eval_ctx, ob, NULL);
500 void AbcExporter::exploreObject(EvaluationContext *eval_ctx, Object *ob, Object *dupliObParent)
502 /* If an object isn't exported itself, its duplilist shouldn't be
503 * exported either. */
504 if (!export_object(&m_settings, ob, dupliObParent != NULL)) {
508 createShapeWriter(ob, dupliObParent);
510 ListBase *lb = object_duplilist(eval_ctx, m_scene, ob);
513 DupliObject *link = static_cast<DupliObject *>(lb->first);
515 for (; link; link = link->next) {
516 /* This skips things like custom bone shapes. */
517 if (m_settings.renderable_only && link->no_draw) {
521 if (link->type == OB_DUPLIGROUP) {
522 exploreObject(eval_ctx, link->ob, ob);
527 free_object_duplilist(lb);
530 void AbcExporter::createParticleSystemsWriters(Object *ob, AbcTransformWriter *xform)
532 if (!m_settings.export_hair && !m_settings.export_particles) {
536 ParticleSystem *psys = static_cast<ParticleSystem *>(ob->particlesystem.first);
538 for (; psys; psys = psys->next) {
539 if (!psys_check_enabled(ob, psys, G.is_rendering) || !psys->part) {
543 if (m_settings.export_hair && psys->part->type == PART_HAIR) {
544 m_settings.export_child_hairs = true;
545 m_shapes.push_back(new AbcHairWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys));
547 else if (m_settings.export_particles && psys->part->type == PART_EMITTER) {
548 m_shapes.push_back(new AbcPointsWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys));
553 void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent)
555 if (!object_is_shape(ob)) {
561 if (m_settings.flatten_hierarchy) {
562 name = get_id_name(ob);
565 name = get_object_dag_path_name(ob, dupliObParent);
568 AbcTransformWriter *xform = getXForm(name);
571 ABC_LOG(m_settings.logger) << __func__ << ": xform " << name << " is NULL\n";
575 createParticleSystemsWriters(ob, xform);
580 Mesh *me = static_cast<Mesh *>(ob->data);
582 if (!me || me->totvert == 0) {
586 m_shapes.push_back(new AbcMeshWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings));
591 Curve *cu = static_cast<Curve *>(ob->data);
597 m_shapes.push_back(new AbcNurbsWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings));
602 Curve *cu = static_cast<Curve *>(ob->data);
608 m_shapes.push_back(new AbcCurveWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings));
613 Camera *cam = static_cast<Camera *>(ob->data);
615 if (cam->type == CAM_PERSP) {
616 m_shapes.push_back(new AbcCameraWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings));
624 AbcTransformWriter *AbcExporter::getXForm(const std::string &name)
626 std::map<std::string, AbcTransformWriter *>::iterator it = m_xforms.find(name);
628 if (it == m_xforms.end()) {
635 void AbcExporter::setCurrentFrame(Main *bmain, double t)
637 m_scene->r.cfra = static_cast<int>(t);
638 m_scene->r.subframe = static_cast<float>(t) - m_scene->r.cfra;
639 BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, m_scene, m_scene->lay);