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 +++++++++++++-------------- source/blender/alembic/intern/abc_exporter.h | 14 +++--- source/blender/alembic/intern/alembic_capi.cc | 4 +- 3 files changed, 39 insertions(+), 41 deletions(-) (limited to 'source/blender/alembic/intern') 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) { diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h index 797a2560d65..f763922a73b 100644 --- a/source/blender/alembic/intern/abc_exporter.h +++ b/source/blender/alembic/intern/abc_exporter.h @@ -50,8 +50,8 @@ struct ExportSettings { bool renderable_only; double frame_start, frame_end; - double frame_step_xform; - double frame_step_shape; + double frame_samples_xform; + double frame_samples_shape; double shutter_open; double shutter_close; float global_scale; @@ -103,13 +103,15 @@ public: void operator()(Main *bmain, float &progress, bool &was_canceled); -private: - void getShutterSamples(double step, bool time_relative, std::vector &samples); +protected: + void getShutterSamples(unsigned int nr_of_samples, + bool time_relative, + std::vector &samples); + void getFrameSet(unsigned int nr_of_samples, std::set &frames); +private: Alembic::Abc::TimeSamplingPtr createTimeSampling(double step); - void getFrameSet(double step, std::set &frames); - void createTransformWritersHierarchy(EvaluationContext *eval_ctx); AbcTransformWriter * createTransformWriter(Object *ob, Object *parent, Object *dupliObParent); void exploreTransform(EvaluationContext *eval_ctx, Object *ob, Object *parent, Object *dupliObParent = NULL); diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc index 52864799133..cb45ee643cd 100644 --- a/source/blender/alembic/intern/alembic_capi.cc +++ b/source/blender/alembic/intern/alembic_capi.cc @@ -332,8 +332,8 @@ bool ABC_export( job->settings.scene = job->scene; job->settings.frame_start = params->frame_start; job->settings.frame_end = params->frame_end; - job->settings.frame_step_xform = params->frame_step_xform; - job->settings.frame_step_shape = params->frame_step_shape; + job->settings.frame_samples_xform = params->frame_samples_xform; + job->settings.frame_samples_shape = params->frame_samples_shape; job->settings.shutter_open = params->shutter_open; job->settings.shutter_close = params->shutter_close; job->settings.selected_only = params->selected_only; -- cgit v1.2.3