From de3c98d62b1ec8e9ad9ea01cb85d47064751ba24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 11 Apr 2017 14:07:26 +0200 Subject: Alembic export: removed superfluous export_object() check. The exploreTransform() function already does this check, and the check isn't necessary when the object type isn't exported anyway. --- source/blender/alembic/intern/abc_exporter.cc | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index ec9504a2f3a..76167fc435d 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -349,18 +349,16 @@ void AbcExporter::createTransformWritersHierarchy(EvaluationContext *eval_ctx) while (base) { Object *ob = base->object; - if (export_object(&m_settings, ob)) { - switch (ob->type) { - case OB_LAMP: - case OB_LATTICE: - case OB_MBALL: - case OB_SPEAKER: - /* We do not export transforms for objects of these classes. */ - break; - - default: - exploreTransform(eval_ctx, ob, ob->parent, NULL); - } + switch (ob->type) { + case OB_LAMP: + case OB_LATTICE: + case OB_MBALL: + case OB_SPEAKER: + /* We do not export transforms for objects of these classes. */ + break; + + default: + exploreTransform(eval_ctx, ob, ob->parent); } base = base->next; -- cgit v1.2.3 From 642728b3395a49895526348e7a8b294e72ef6dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Wed, 12 Apr 2017 12:15:32 +0200 Subject: Alembic export: fixed exporting as "flat" This exports all objects in world coordinates without parenting. --- source/blender/alembic/intern/abc_exporter.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index 76167fc435d..39896529c97 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -374,7 +374,9 @@ void AbcExporter::createTransformWritersFlat() if (export_object(&m_settings, ob) && object_is_shape(ob)) { std::string name = get_id_name(ob); - m_xforms[name] = new AbcTransformWriter(ob, m_writer->archive().getTop(), 0, m_trans_sampling_index, m_settings); + m_xforms[name] = new AbcTransformWriter( + ob, m_writer->archive().getTop(), NULL, + m_trans_sampling_index, m_settings); } base = base->next; -- cgit v1.2.3 From ebb30451140296970af011a15579c52731b610e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Wed, 12 Apr 2017 12:35:09 +0200 Subject: Alembic export: added support for writing dupli-groups This supports our common character animation workflow, where a character, its rig, and the custom bone shapes are all part of a group. This group is then linked into the scene, the rig is proxified and animated. Such a group can now be exported. Use "Renderable objects only" to prevent writing the custom bone shapes to the Alembic file. --- source/blender/alembic/intern/abc_exporter.cc | 68 ++++++++++++++++++++------- 1 file changed, 51 insertions(+), 17 deletions(-) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index 39896529c97..c58aedd6503 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -124,14 +124,32 @@ static bool object_is_shape(Object *ob) } } -static bool export_object(const ExportSettings * const settings, Object *ob) + +/** + * Returns whether this object should be exported into the Alembic file. + * + * @param settings export settings, used for options like 'selected only'. + * @param ob the object in question. + * @param is_duplicated normally false; true when the object is instanced + * into the scene by a dupli-object (e.g. part of a + * dupligroup). This ignores selection and layer + * visibility, and assumes that the dupli-object itself + * (e.g. the group-instantiating empty) is exported. + */ +static bool export_object(const ExportSettings * const settings, Object *ob, + bool is_duplicated) { - if (settings->selected_only && !parent_selected(ob)) { - return false; - } + if (!is_duplicated) { + /* These two tests only make sense when the object isn't being instanced + * into the scene. When it is, its exportability is determined by + * its dupli-object and the DupliObject::no_draw property. */ + if (settings->selected_only && !parent_selected(ob)) { + return false; + } - if (settings->visible_layers_only && !(settings->scene->lay & ob->lay)) { - return false; + if (settings->visible_layers_only && !(settings->scene->lay & ob->lay)) { + return false; + } } if (settings->renderable_only && (ob->restrictflag & OB_RESTRICT_RENDER)) { @@ -372,7 +390,7 @@ void AbcExporter::createTransformWritersFlat() while (base) { Object *ob = base->object; - if (export_object(&m_settings, ob) && object_is_shape(ob)) { + if (export_object(&m_settings, ob, false) && object_is_shape(ob)) { std::string name = get_id_name(ob); m_xforms[name] = new AbcTransformWriter( ob, m_writer->archive().getTop(), NULL, @@ -385,8 +403,13 @@ void AbcExporter::createTransformWritersFlat() void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Object *ob, Object *parent, Object *dupliObParent) { + /* If an object isn't exported itself, its duplilist shouldn't be + * exported either. */ + if (!export_object(&m_settings, ob, dupliObParent != NULL)) { + return; + } - if (export_object(&m_settings, ob) && object_is_shape(ob)) { + if (object_is_shape(ob)) { createTransformWriter(ob, parent, dupliObParent); } @@ -397,15 +420,18 @@ void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Object *ob, Obje Object *dupli_ob = NULL; Object *dupli_parent = NULL; - while (link) { + for (; link; link = link->next) { + /* This skips things like custom bone shapes. */ + if (m_settings.renderable_only && link->no_draw) { + continue; + } + if (link->type == OB_DUPLIGROUP) { dupli_ob = link->ob; dupli_parent = (dupli_ob->parent) ? dupli_ob->parent : ob; exploreTransform(eval_ctx, dupli_ob, dupli_parent, ob); } - - link = link->next; } } @@ -478,14 +504,26 @@ void AbcExporter::createShapeWriters(EvaluationContext *eval_ctx) void AbcExporter::exploreObject(EvaluationContext *eval_ctx, Object *ob, Object *dupliObParent) { - ListBase *lb = object_duplilist(eval_ctx, m_scene, ob); - + /* If an object isn't exported itself, its duplilist shouldn't be + * exported either. */ + if (!export_object(&m_settings, ob, dupliObParent != NULL)) { + return; + } + createShapeWriter(ob, dupliObParent); + ListBase *lb = object_duplilist(eval_ctx, m_scene, ob); + if (lb) { DupliObject *dupliob = static_cast(lb->first); while (dupliob) { + /* This skips things like custom bone shapes. */ + if (m_settings.renderable_only && dupliob->no_draw) { + dupliob = dupliob->next; + continue; + } + if (dupliob->type == OB_DUPLIGROUP) { exploreObject(eval_ctx, dupliob->ob, ob); } @@ -503,10 +541,6 @@ void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent) return; } - if (!export_object(&m_settings, ob)) { - return; - } - std::string name; if (m_settings.flatten_hierarchy) { -- cgit v1.2.3 From 3906e5939ab5ce5a1518d16c47cf6289c876aa92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 11 Apr 2017 14:59:48 +0200 Subject: Alembic export: unified code of exploreTransform and exploreObject. --- source/blender/alembic/intern/abc_exporter.cc | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index c58aedd6503..a8d1587abdb 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -515,20 +515,17 @@ void AbcExporter::exploreObject(EvaluationContext *eval_ctx, Object *ob, Object ListBase *lb = object_duplilist(eval_ctx, m_scene, ob); if (lb) { - DupliObject *dupliob = static_cast(lb->first); + DupliObject *link = static_cast(lb->first); - while (dupliob) { + for (; link; link = link->next) { /* This skips things like custom bone shapes. */ - if (m_settings.renderable_only && dupliob->no_draw) { - dupliob = dupliob->next; + if (m_settings.renderable_only && link->no_draw) { continue; } - if (dupliob->type == OB_DUPLIGROUP) { - exploreObject(eval_ctx, dupliob->ob, ob); + if (link->type == OB_DUPLIGROUP) { + exploreObject(eval_ctx, link->ob, ob); } - - dupliob = dupliob->next; } } -- cgit v1.2.3 From 4d117f2fd2438989d90b40f38d2ca1625be9e6e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 14 Apr 2017 16:38:26 +0200 Subject: Alembic export: fixed flattened dupligroup import --- source/blender/alembic/intern/abc_exporter.cc | 48 +++++++++------------------ 1 file changed, 15 insertions(+), 33 deletions(-) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index a8d1587abdb..d949df1b20a 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -290,13 +290,7 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled) OBox3dProperty archive_bounds_prop = Alembic::AbcGeom::CreateOArchiveBounds(m_writer->archive(), m_trans_sampling_index); - if (m_settings.flatten_hierarchy) { - createTransformWritersFlat(); - } - else { - createTransformWritersHierarchy(bmain->eval_ctx); - } - + createTransformWritersHierarchy(bmain->eval_ctx); createShapeWriters(bmain->eval_ctx); /* Make a list of frames to export. */ @@ -383,24 +377,6 @@ void AbcExporter::createTransformWritersHierarchy(EvaluationContext *eval_ctx) } } -void AbcExporter::createTransformWritersFlat() -{ - Base *base = static_cast(m_scene->base.first); - - while (base) { - Object *ob = base->object; - - if (export_object(&m_settings, ob, false) && object_is_shape(ob)) { - std::string name = get_id_name(ob); - m_xforms[name] = new AbcTransformWriter( - ob, m_writer->archive().getTop(), NULL, - m_trans_sampling_index, m_settings); - } - - base = base->next; - } -} - void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Object *ob, Object *parent, Object *dupliObParent) { /* If an object isn't exported itself, its duplilist shouldn't be @@ -440,12 +416,18 @@ void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Object *ob, Obje AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *parent, Object *dupliObParent) { - const std::string name = get_object_dag_path_name(ob, dupliObParent); - /* An object should not be its own parent, or we'll get infinite loops. */ BLI_assert(ob != parent); BLI_assert(ob != dupliObParent); + std::string name; + if (m_settings.flatten_hierarchy) { + name = get_id_name(ob); + } + else { + name = get_object_dag_path_name(ob, dupliObParent); + } + /* check if we have already created a transform writer for this object */ AbcTransformWriter *my_writer = getXForm(name); if (my_writer != NULL){ @@ -455,7 +437,12 @@ AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *pare AbcTransformWriter *parent_writer = NULL; Alembic::Abc::OObject alembic_parent; - if (parent) { + if (m_settings.flatten_hierarchy || parent == NULL) { + /* Parentless objects still have the "top object" as parent + * in Alembic. */ + alembic_parent = m_writer->archive().getTop(); + } + else { /* Since there are so many different ways to find parents (as evident * in the number of conditions below), we can't really look up the * parent by name. We'll just call createTransformWriter(), which will @@ -478,11 +465,6 @@ AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *pare BLI_assert(parent_writer); alembic_parent = parent_writer->alembicXform(); } - else { - /* Parentless objects still have the "top object" as parent - * in Alembic. */ - alembic_parent = m_writer->archive().getTop(); - } my_writer = new AbcTransformWriter(ob, alembic_parent, parent_writer, m_trans_sampling_index, m_settings); -- cgit v1.2.3 From 5fa4f397c2050fa15e28855acae1520377a4a517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 14 Apr 2017 18:20:24 +0200 Subject: Alembic import: fixed dupligroup export when the dupli-empty has a parent --- source/blender/alembic/intern/abc_exporter.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index d949df1b20a..ef3196cb15d 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -448,7 +448,12 @@ AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *pare * parent by name. We'll just call createTransformWriter(), which will * return the parent's AbcTransformWriter pointer. */ if (parent->parent) { - parent_writer = createTransformWriter(parent, parent->parent, dupliObParent); + if (parent == dupliObParent) { + parent_writer = createTransformWriter(parent, parent->parent, NULL); + } + else { + parent_writer = createTransformWriter(parent, parent->parent, dupliObParent); + } } else if (parent == dupliObParent) { if (dupliObParent->parent == NULL) { @@ -468,6 +473,12 @@ AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *pare my_writer = new AbcTransformWriter(ob, alembic_parent, parent_writer, m_trans_sampling_index, m_settings); + + /* When flattening, the matrix of the dupliobject has to be added. */ + if (m_settings.flatten_hierarchy && dupliObParent) { + my_writer->m_proxy_from = dupliObParent; + } + m_xforms[name] = my_writer; return my_writer; } -- cgit v1.2.3 From b148ac5cf77a869bcca5b51716141400bb90a70d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Wed, 19 Apr 2017 13:03:52 +0200 Subject: Alembic export: made hair/particle export optional. The export is still slower than needed, as the particle systems themselves aren't disabled during the export. It's only the writing to the Alembic file that's skipped. --- source/blender/alembic/intern/abc_exporter.cc | 41 +++++++++++++++++---------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index ef3196cb15d..d70b9625f1d 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -83,6 +83,8 @@ ExportSettings::ExportSettings() , export_vcols(false) , export_face_sets(false) , export_vweigths(false) + , export_hair(true) + , export_particles(true) , apply_subdiv(false) , use_subdiv_schema(false) , export_child_hairs(true) @@ -525,6 +527,29 @@ void AbcExporter::exploreObject(EvaluationContext *eval_ctx, Object *ob, Object free_object_duplilist(lb); } +void AbcExporter::createParticleSystemsWriters(Object *ob, AbcTransformWriter *xform) +{ + if (!m_settings.export_hair && !m_settings.export_particles) { + return; + } + + ParticleSystem *psys = static_cast(ob->particlesystem.first); + + for (; psys; psys = psys->next) { + if (!psys_check_enabled(ob, psys, G.is_rendering) || !psys->part) { + continue; + } + + if (m_settings.export_hair && psys->part->type == PART_HAIR) { + m_settings.export_child_hairs = true; + m_shapes.push_back(new AbcHairWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys)); + } + else if (m_settings.export_particles && psys->part->type == PART_EMITTER) { + m_shapes.push_back(new AbcPointsWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys)); + } + } +} + void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent) { if (!object_is_shape(ob)) { @@ -547,21 +572,7 @@ void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent) return; } - ParticleSystem *psys = static_cast(ob->particlesystem.first); - - for (; psys; psys = psys->next) { - if (!psys_check_enabled(ob, psys, G.is_rendering) || !psys->part) { - continue; - } - - if (psys->part->type == PART_HAIR) { - m_settings.export_child_hairs = true; - m_shapes.push_back(new AbcHairWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys)); - } - else if (psys->part->type == PART_EMITTER) { - m_shapes.push_back(new AbcPointsWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys)); - } - } + createParticleSystemsWriters(ob, xform); switch (ob->type) { case OB_MESH: -- cgit v1.2.3 From afe1c25d06794177f0cbb9fcb87b05e45eee0b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Wed, 26 Apr 2017 12:25:45 +0200 Subject: =?UTF-8?q?Alembic=20export:=20renamed=20func=20object=5Fis=5Fshap?= =?UTF-8?q?e=20=E2=86=92=20object=5Ftype=5Fis=5Fexportable?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The function doesn't return whether the object is a shape at all, since it also returns true for camera objects (and soon also for empties). It returns true when objects of this type can be exported to Alembic at all. This is now reflected in the name. --- source/blender/alembic/intern/abc_exporter.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index d70b9625f1d..87963151656 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -108,7 +108,7 @@ static bool object_is_smoke_sim(Object *ob) return false; } -static bool object_is_shape(Object *ob) +static bool object_type_is_exportable(Object *ob) { switch (ob->type) { case OB_MESH: @@ -387,7 +387,7 @@ void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Object *ob, Obje return; } - if (object_is_shape(ob)) { + if (object_type_is_exportable(ob)) { createTransformWriter(ob, parent, dupliObParent); } @@ -552,7 +552,7 @@ void AbcExporter::createParticleSystemsWriters(Object *ob, AbcTransformWriter *x void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent) { - if (!object_is_shape(ob)) { + if (!object_type_is_exportable(ob)) { return; } -- cgit v1.2.3 From 9b3e3d4defc66be82fd53552b380d42091c028c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Wed, 26 Apr 2017 12:26:21 +0200 Subject: Alembic export: also export empties Exporting an empty creates an Alembic XForm object. The empties can also be animated. --- source/blender/alembic/intern/abc_exporter.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index 87963151656..11c63461ab4 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -117,6 +117,7 @@ static bool object_type_is_exportable(Object *ob) } return true; + case OB_EMPTY: case OB_CURVE: case OB_SURF: case OB_CAMERA: -- cgit v1.2.3 From 6715bfee92e72dd91a4bebd2fd81f817036f3a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Wed, 24 May 2017 12:39:37 +0200 Subject: Alembic: Export mesh as mesh, even when it has no vertices. This makes it possible to have an animated / procedurally generated mesh that starts empty and obtains data in later frames. Fixes the export of an empty mesh with an Ocean Modifier, as described in issue T51351. --- source/blender/alembic/intern/abc_exporter.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index 11c63461ab4..1fb59357f5d 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -580,7 +580,7 @@ void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent) { Mesh *me = static_cast(ob->data); - if (!me || me->totvert == 0) { + if (!me) { return; } -- cgit v1.2.3 From cfce8623a808d04904e00ac93d7d90d369a569e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 26 May 2017 12:55:07 +0200 Subject: Alembic export: prevent rounding error buildup in frame sample time --- source/blender/alembic/intern/abc_exporter.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index 1fb59357f5d..ced58e4964e 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -209,8 +209,10 @@ void AbcExporter::getShutterSamples(double step, bool time_relative, const int nsamples = static_cast(std::max((1.0 / step) - 1.0, 1.0)); const double time_inc = (shutter_close - shutter_open) / nsamples; - for (double t = shutter_open; t <= shutter_close; t += time_inc) { - samples.push_back((t + m_settings.frame_start) / time_factor); + for (int sample=0; sample < nsamples; ++sample) { + double sample_time = shutter_open + time_inc * sample; + double time = (m_settings.frame_start + sample_time) / time_factor; + samples.push_back(time); } } } -- cgit v1.2.3 From 4aeba3b90dac780d25fd04c174b5cdc4da53efd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Fri, 26 May 2017 12:56:27 +0200 Subject: Alembic export: avoid create-and-reset of shared pointer Constructing the shared pointer where the object is actually allocated makes the code a bit clearer. --- source/blender/alembic/intern/abc_exporter.cc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index ced58e4964e..0c0d73713fb 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -219,20 +219,17 @@ void AbcExporter::getShutterSamples(double step, bool time_relative, Alembic::Abc::TimeSamplingPtr AbcExporter::createTimeSampling(double step) { - TimeSamplingPtr time_sampling; std::vector samples; if (m_settings.frame_start == m_settings.frame_end) { - time_sampling.reset(new Alembic::Abc::TimeSampling()); - return time_sampling; + return TimeSamplingPtr(new Alembic::Abc::TimeSampling()); } getShutterSamples(step, true, samples); Alembic::Abc::TimeSamplingType ts(static_cast(samples.size()), 1.0 / m_scene->r.frs_sec); - time_sampling.reset(new Alembic::Abc::TimeSampling(ts, samples)); - return time_sampling; + return TimeSamplingPtr(new Alembic::Abc::TimeSampling(ts, samples)); } void AbcExporter::getFrameSet(double step, std::set &frames) -- cgit v1.2.3 From 35f4abcf53dad7c4aa83a677f8d6d9e85b7f2b12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= Date: Tue, 30 May 2017 13:39:36 +0200 Subject: Alembic: simplified sub-frame sampling It's now less confusing (for example, using nr_of_samples directly, instead of using 1 / 1 / nr_of_samples). Might also have fixed a bug. Also added unittests. --- source/blender/alembic/intern/abc_exporter.cc | 62 +++++++++++++-------------- 1 file changed, 29 insertions(+), 33 deletions(-) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index 0c0d73713fb..3da67ac0865 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -72,8 +72,8 @@ ExportSettings::ExportSettings() , renderable_only(false) , frame_start(1) , frame_end(1) - , frame_step_xform(1) - , frame_step_shape(1) + , frame_samples_xform(1) + , frame_samples_shape(1) , shutter_open(0.0) , shutter_close(1.0) , global_scale(1.0f) @@ -189,31 +189,25 @@ AbcExporter::~AbcExporter() delete m_writer; } -void AbcExporter::getShutterSamples(double step, bool time_relative, +void AbcExporter::getShutterSamples(unsigned int nr_of_samples, + bool time_relative, std::vector &samples) { + Scene *scene = m_scene; /* for use in the FPS macro */ samples.clear(); - const double time_factor = time_relative ? m_scene->r.frs_sec : 1.0; - const double shutter_open = m_settings.shutter_open; - const double shutter_close = m_settings.shutter_close; + unsigned int frame_offset = time_relative ? m_settings.frame_start : 0; + double time_factor = time_relative ? FPS : 1.0; + double shutter_open = m_settings.shutter_open; + double shutter_close = m_settings.shutter_close; + double time_inc = (shutter_close - shutter_open) / nr_of_samples; - /* sample all frame */ - if (shutter_open == 0.0 && shutter_close == 1.0) { - for (double t = 0.0; t < 1.0; t += step) { - samples.push_back((t + m_settings.frame_start) / time_factor); - } - } - else { - /* sample between shutter open & close */ - const int nsamples = static_cast(std::max((1.0 / step) - 1.0, 1.0)); - const double time_inc = (shutter_close - shutter_open) / nsamples; - - for (int sample=0; sample < nsamples; ++sample) { - double sample_time = shutter_open + time_inc * sample; - double time = (m_settings.frame_start + sample_time) / time_factor; - samples.push_back(time); - } + /* sample between shutter open & close */ + for (int sample=0; sample < nr_of_samples; ++sample) { + double sample_time = shutter_open + time_inc * sample; + double time = (frame_offset + sample_time) / time_factor; + + samples.push_back(time); } } @@ -227,21 +221,24 @@ Alembic::Abc::TimeSamplingPtr AbcExporter::createTimeSampling(double step) getShutterSamples(step, true, samples); - Alembic::Abc::TimeSamplingType ts(static_cast(samples.size()), 1.0 / m_scene->r.frs_sec); + Alembic::Abc::TimeSamplingType ts( + static_cast(samples.size()), + 1.0 / m_scene->r.frs_sec); return TimeSamplingPtr(new Alembic::Abc::TimeSampling(ts, samples)); } -void AbcExporter::getFrameSet(double step, std::set &frames) +void AbcExporter::getFrameSet(unsigned int nr_of_samples, + std::set &frames) { frames.clear(); std::vector shutter_samples; - getShutterSamples(step, false, shutter_samples); + getShutterSamples(nr_of_samples, false, shutter_samples); for (double frame = m_settings.frame_start; frame <= m_settings.frame_end; frame += 1.0) { - for (int j = 0, e = shutter_samples.size(); j < e; ++j) { + for (size_t j = 0; j < nr_of_samples; ++j) { frames.insert(frame + shutter_samples[j]); } } @@ -273,20 +270,20 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled) /* Create time samplings for transforms and shapes. */ - TimeSamplingPtr trans_time = createTimeSampling(m_settings.frame_step_xform); + TimeSamplingPtr trans_time = createTimeSampling(m_settings.frame_samples_xform); m_trans_sampling_index = m_writer->archive().addTimeSampling(*trans_time); TimeSamplingPtr shape_time; - if ((m_settings.frame_step_shape == m_settings.frame_step_xform) || + if ((m_settings.frame_samples_shape == m_settings.frame_samples_xform) || (m_settings.frame_start == m_settings.frame_end)) { shape_time = trans_time; m_shape_sampling_index = m_trans_sampling_index; } else { - shape_time = createTimeSampling(m_settings.frame_step_shape); + shape_time = createTimeSampling(m_settings.frame_samples_shape); m_shape_sampling_index = m_writer->archive().addTimeSampling(*shape_time); } @@ -298,13 +295,12 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled) /* Make a list of frames to export. */ std::set xform_frames; - getFrameSet(m_settings.frame_step_xform, xform_frames); + getFrameSet(m_settings.frame_samples_xform, xform_frames); std::set shape_frames; - getFrameSet(m_settings.frame_step_shape, shape_frames); + getFrameSet(m_settings.frame_samples_shape, shape_frames); /* Merge all frames needed. */ - std::set frames(xform_frames); frames.insert(shape_frames.begin(), shape_frames.end()); @@ -327,7 +323,7 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled) const double frame = *begin; /* 'frame' is offset by start frame, so need to cancel the offset. */ - setCurrentFrame(bmain, frame - m_settings.frame_start); + setCurrentFrame(bmain, frame); if (shape_frames.count(frame) != 0) { for (int i = 0, e = m_shapes.size(); i != e; ++i) { -- cgit v1.2.3 From 0d8bf4bf947d84cdfc6e2b221ddb03c7f8d2114b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 2 Jun 2017 15:38:04 +1000 Subject: Cleanup: style --- source/blender/alembic/intern/abc_exporter.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index 3da67ac0865..3f359990980 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -428,7 +428,7 @@ AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *pare /* check if we have already created a transform writer for this object */ AbcTransformWriter *my_writer = getXForm(name); - if (my_writer != NULL){ + if (my_writer != NULL) { return my_writer; } -- cgit v1.2.3 From 72c9141a7a56fa4762ac0daae501f1609532506c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 19 Jun 2017 09:33:23 +1000 Subject: Cleanup: doxygen comments Also remove duplicate & mismatching comments from grease-pencil header. Keep comments close to implementation to avoid getting out of sync. --- source/blender/alembic/intern/abc_exporter.cc | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'source/blender/alembic/intern/abc_exporter.cc') diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc index 3f359990980..4fe65b96f36 100644 --- a/source/blender/alembic/intern/abc_exporter.cc +++ b/source/blender/alembic/intern/abc_exporter.cc @@ -131,13 +131,12 @@ static bool object_type_is_exportable(Object *ob) /** * Returns whether this object should be exported into the Alembic file. * - * @param settings export settings, used for options like 'selected only'. - * @param ob the object in question. - * @param is_duplicated normally false; true when the object is instanced - * into the scene by a dupli-object (e.g. part of a - * dupligroup). This ignores selection and layer - * visibility, and assumes that the dupli-object itself - * (e.g. the group-instantiating empty) is exported. + * \param settings: export settings, used for options like 'selected only'. + * \param ob: the object in question. + * \param is_duplicated: Normally false; true when the object is instanced + * into the scene by a dupli-object (e.g. part of a dupligroup). + * This ignores selection and layer visibility, + * and assumes that the dupli-object itself (e.g. the group-instantiating empty) is exported. */ static bool export_object(const ExportSettings * const settings, Object *ob, bool is_duplicated) -- cgit v1.2.3