From b5341c7d794c1009f2490a7d566036049e62ba35 Mon Sep 17 00:00:00 2001 From: mfeemster Date: Thu, 5 May 2016 16:11:30 -0700 Subject: [PATCH] --User changes -Remove --time option for EmberAnimate, it was redundant with --frame. -Make --enable_jpg_comments and --enable_png_comments just be bools that when present mean true, rather than having to specify =true. -Add a new argument --ts for EmberAnimate to allow the user to specify the temporal samples value to use for the entire animation. Useful for testing. --Bug fixes -Properly seed rands in EmberAnimate when specifying --isaac_seed and using more than one device with --opencl. --Code changes --Small cleanup to flatten/unflatten all code. --Make EmberOptionEntry::operator() return a const reference instead of a copy. --- Source/EmberAnimate/EmberAnimate.cpp | 58 +++++++++++++-------------- Source/EmberCommon/EmberOptions.h | 42 +++++++++---------- Source/Fractorium/FractoriumMenus.cpp | 12 +----- 3 files changed, 50 insertions(+), 62 deletions(-) diff --git a/Source/EmberAnimate/EmberAnimate.cpp b/Source/EmberAnimate/EmberAnimate.cpp index c85c1fd..ac99d72 100644 --- a/Source/EmberAnimate/EmberAnimate.cpp +++ b/Source/EmberAnimate/EmberAnimate.cpp @@ -78,8 +78,25 @@ bool EmberAnimate(EmberOptions& opt) opt.ThreadCount(1); - for (auto& r : renderers) - r->ThreadCount(opt.ThreadCount(), opt.IsaacSeed() != "" ? opt.IsaacSeed().c_str() : nullptr); + if (opt.IsaacSeed().empty()) + { + for (auto& r : renderers) + r->ThreadCount(opt.ThreadCount(), nullptr); + } + else + { + for (i = 0; i < renderers.size(); i++) + { + string ns; + auto& is = opt.IsaacSeed(); + ns.reserve(is.size()); + + for (auto& c : is) + ns.push_back(c + char(i * opt.ThreadCount())); + + renderers[i]->ThreadCount(opt.ThreadCount(), ns.c_str()); + } + } if (opt.BitsPerChannel() != 8) { @@ -167,34 +184,16 @@ bool EmberAnimate(EmberOptions& opt) opt.Dtime(1); } - if (opt.Frame()) + if (opt.Frame() != UINT_MAX) { - if (opt.Time()) - { - cout << "Cannot specify both time and frame.\n"; - return false; - } - - if (opt.FirstFrame() || opt.LastFrame()) + if (opt.FirstFrame() != UINT_MAX || opt.LastFrame() != UINT_MAX) { cout << "Cannot specify both frame and begin or end.\n"; return false; } opt.FirstFrame(opt.Frame()); - opt.LastFrame(opt.Frame()); - } - - if (opt.Time()) - { - if (opt.FirstFrame() || opt.LastFrame()) - { - cout << "Cannot specify both time and begin or end.\n"; - return false; - } - - opt.FirstFrame(opt.Time()); - opt.LastFrame(opt.Time()); + opt.LastFrame(opt.Frame() + 1); } //Prep all embers, by ensuring they: @@ -222,6 +221,9 @@ bool EmberAnimate(EmberOptions& opt) if (opt.Supersample() > 0) embers[i].m_Supersample = opt.Supersample(); + if (opt.TemporalSamples() > 0) + embers[i].m_TemporalSamples = opt.TemporalSamples(); + if (opt.Quality() > 0) embers[i].m_Quality = T(opt.Quality()); @@ -270,7 +272,7 @@ bool EmberAnimate(EmberOptions& opt) std::sort(embers.begin(), embers.end(), &CompareEmbers); } - if (!opt.Time() && !opt.Frame()) + if (opt.Frame() == UINT_MAX) { if (opt.FirstFrame() == UINT_MAX) opt.FirstFrame(size_t(embers[0].m_Time)); @@ -280,12 +282,6 @@ bool EmberAnimate(EmberOptions& opt) opt.FirstFrame() + opt.Dtime()));//Make sure the final value is at least first frame + dtime. } - if (!opt.Out().empty()) - { - cout << "Single output file " << opt.Out() << " specified for multiple images. They would be all overwritten and only the last image will remain, exiting.\n"; - return false; - } - //Final setup steps before running. padding = uint(std::log10(double(embers.size()))) + 1; @@ -366,7 +362,7 @@ bool EmberAnimate(EmberOptions& opt) if ((renderer->Run(finalImages[finalImageIndex], localTime) != eRenderStatus::RENDER_OK) || renderer->Aborted() || finalImages[finalImageIndex].empty()) { - cout << "Error: image rendering failed, skipping to next image.\n"; + cout << "Error: image rendering failed, aborting.\n"; renderer->DumpErrorReport();//Something went wrong, print errors. atomfTime.store(opt.LastFrame() + 1);//Abort all threads if any of them encounter an error. break; diff --git a/Source/EmberCommon/EmberOptions.h b/Source/EmberCommon/EmberOptions.h index 38cfd32..c31ef96 100644 --- a/Source/EmberCommon/EmberOptions.h +++ b/Source/EmberCommon/EmberOptions.h @@ -64,13 +64,13 @@ enum class eOptionIDs : et OPT_NTHREADS,//Int value args. OPT_STRIPS, OPT_SUPERSAMPLE, + OPT_TEMPSAMPLES, OPT_BPC, OPT_PRINT_EDIT_DEPTH, OPT_JPEG, OPT_BEGIN, OPT_END, OPT_FRAME, - OPT_TIME, OPT_DTIME, OPT_NFRAMES, OPT_SYMMETRY, @@ -200,7 +200,7 @@ public: /// /// Functor accessors. /// - inline T operator() (void) const { return m_Val; } + inline const T& operator() (void) const { return m_Val; } inline void operator() (T t) { m_Val = t; } private: @@ -320,8 +320,8 @@ public: INITBOOLOPTION(NameEnable, Eob(eOptionUse::OPT_USE_RENDER, eOptionIDs::OPT_NAME_ENABLE, _T("--name_enable"), false, SO_NONE, "\t--name_enable Use the name attribute contained in the Xml as the output filename [default: false].\n")); INITBOOLOPTION(HexPalette, Eob(eOptionUse::OPT_ANIM_GENOME, eOptionIDs::OPT_HEX_PALETTE, _T("--hex_palette"), true, SO_OPT, "\t--hex_palette Force palette RGB values to be hex when saving to Xml [default: true].\n")); INITBOOLOPTION(InsertPalette, Eob(eOptionUse::OPT_USE_RENDER, eOptionIDs::OPT_INSERT_PALETTE, _T("--insert_palette"), false, SO_NONE, "\t--insert_palette Insert the palette into the image for debugging purposes. Disabled when running with OpenCL [default: false].\n")); - INITBOOLOPTION(JpegComments, Eob(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_JPEG_COMMENTS, _T("--enable_jpeg_comments"), false, SO_OPT, "\t--enable_jpeg_comments Enables embedding the flame parameters and user identifying information in the jpeg header [default: false].\n")); - INITBOOLOPTION(PngComments, Eob(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_PNG_COMMENTS, _T("--enable_png_comments"), false, SO_OPT, "\t--enable_png_comments Enables embedding the flame parameters and user identifying information png header [default: false].\n")); + INITBOOLOPTION(JpegComments, Eob(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_JPEG_COMMENTS, _T("--enable_jpg_comments"), false, SO_NONE, "\t--enable_jpg_comments Enables embedding the flame parameters and user identifying information in the jpeg header [default: false].\n")); + INITBOOLOPTION(PngComments, Eob(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_PNG_COMMENTS, _T("--enable_png_comments"), false, SO_NONE, "\t--enable_png_comments Enables embedding the flame parameters and user identifying information in the png header [default: false].\n")); INITBOOLOPTION(WriteGenome, Eob(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_WRITE_GENOME, _T("--write_genome"), false, SO_NONE, "\t--write_genome Write out flame associated with center of motion blur window [default: false].\n")); INITBOOLOPTION(ThreadedWrite, Eob(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_THREADED_WRITE, _T("--threaded_write"), true, SO_OPT, "\t--threaded_write Use a separate thread to write images to disk. This gives better performance, but doubles the memory required for the final output buffer. [default: true].\n")); INITBOOLOPTION(Enclosed, Eob(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_ENCLOSED, _T("--enclosed"), true, SO_OPT, "\t--enclosed Use enclosing Xml tags [default: true].\n")); @@ -339,21 +339,21 @@ public: INITINTOPTION(Priority, Eoi(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_PRIORITY, _T("--priority"), int(eThreadPriority::NORMAL), SO_REQ_SEP, "\t--priority= The priority of the CPU rendering threads, 1, 25, 50, 75, 99. This does not apply to OpenCL rendering.\n")); #endif //Uint. - INITUINTOPTION(ThreadCount, Eou(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_NTHREADS, _T("--nthreads"), 0, SO_REQ_SEP, "\t--nthreads= The number of threads to use [default: use all available cores].\n")); - INITUINTOPTION(Strips, Eou(eOptionUse::OPT_USE_RENDER, eOptionIDs::OPT_STRIPS, _T("--nstrips"), 1, SO_REQ_SEP, "\t--nstrips= The number of fractions to split a single render frame into. Useful for print size renders or low memory systems [default: 1].\n")); - INITUINTOPTION(Supersample, Eou(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_SUPERSAMPLE, _T("--supersample"), 0, SO_REQ_SEP, "\t--supersample= The supersample value used to override the one specified in the file [default: 0 (use value from file), Range: 0 - 4].\n")); - INITUINTOPTION(BitsPerChannel, Eou(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_BPC, _T("--bpc"), 8, SO_REQ_SEP, "\t--bpc= Bits per channel. 8 or 16 for PNG, 8 for all others, always 8 with OpenCL [default: 8].\n")); - INITUINTOPTION(PrintEditDepth, Eou(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_PRINT_EDIT_DEPTH, _T("--print_edit_depth"), 0, SO_REQ_SEP, "\t--print_edit_depth= Depth to truncate tag structure when converting a flame to Xml. 0 prints all tags [default: 0].\n")); - INITUINTOPTION(JpegQuality, Eou(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_JPEG, _T("--jpeg"), 95, SO_REQ_SEP, "\t--jpeg= Jpeg quality 0-100 for compression [default: 95].\n")); - INITUINTOPTION(FirstFrame, Eou(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_BEGIN, _T("--begin"), UINT_MAX, SO_REQ_SEP, "\t--begin= Time of first frame to render [default: first time specified in file].\n")); - INITUINTOPTION(LastFrame, Eou(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_END, _T("--end"), UINT_MAX, SO_REQ_SEP, "\t--end= Time of last frame to render [default: last time specified in the input file].\n")); - INITUINTOPTION(Time, Eou(eOptionUse::OPT_ANIM_GENOME, eOptionIDs::OPT_TIME, _T("--time"), 0, SO_REQ_SEP, "\t--time= Time of first and last frame (ie do one frame).\n")); - INITUINTOPTION(Frame, Eou(eOptionUse::OPT_ANIM_GENOME, eOptionIDs::OPT_FRAME, _T("--frame"), 0, SO_REQ_SEP, "\t--frame= Synonym for \"time\".\n")); - INITUINTOPTION(Dtime, Eou(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_DTIME, _T("--dtime"), 1, SO_REQ_SEP, "\t--dtime= Time between frames [default: 1].\n")); - INITUINTOPTION(Frames, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_NFRAMES, _T("--nframes"), 20, SO_REQ_SEP, "\t--nframes= Number of frames per loop and per interpolation in the animation [default: 20].\n")); - INITUINTOPTION(Repeat, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_REPEAT, _T("--repeat"), 1, SO_REQ_SEP, "\t--repeat= Number of new flames to create. Ignored if sequence, inter or rotate were specified [default: 1].\n")); - INITUINTOPTION(Tries, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_TRIES, _T("--tries"), 10, SO_REQ_SEP, "\t--tries= Number times to try creating a flame that meets the specified constraints. Ignored if sequence, inter or rotate were specified [default: 10].\n")); - INITUINTOPTION(MaxXforms, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_MAX_XFORMS, _T("--maxxforms"), UINT_MAX, SO_REQ_SEP, "\t--maxxforms= The maximum number of xforms allowed in the final output.\n")); + INITUINTOPTION(ThreadCount, Eou(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_NTHREADS, _T("--nthreads"), 0, SO_REQ_SEP, "\t--nthreads= The number of threads to use [default: use all available cores].\n")); + INITUINTOPTION(Strips, Eou(eOptionUse::OPT_USE_RENDER, eOptionIDs::OPT_STRIPS, _T("--nstrips"), 1, SO_REQ_SEP, "\t--nstrips= The number of fractions to split a single render frame into. Useful for print size renders or low memory systems [default: 1].\n")); + INITUINTOPTION(Supersample, Eou(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_SUPERSAMPLE, _T("--supersample"), 0, SO_REQ_SEP, "\t--supersample= The supersample value used to override the one specified in the file [default: 0 (use value from file), Range: 0 - 4].\n")); + INITUINTOPTION(TemporalSamples, Eou(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_TEMPSAMPLES, _T("--ts"), 0, SO_REQ_SEP, "\t--ts= The temporal samples value used to override all of the temporal sample values specified in the file when animating [default: 0 (use value from file)].\n")); + INITUINTOPTION(BitsPerChannel, Eou(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_BPC, _T("--bpc"), 8, SO_REQ_SEP, "\t--bpc= Bits per channel. 8 or 16 for PNG, 8 for all others, always 8 with OpenCL [default: 8].\n")); + INITUINTOPTION(PrintEditDepth, Eou(eOptionUse::OPT_USE_ALL, eOptionIDs::OPT_PRINT_EDIT_DEPTH, _T("--print_edit_depth"), 0, SO_REQ_SEP, "\t--print_edit_depth= Depth to truncate tag structure when converting a flame to Xml. 0 prints all tags [default: 0].\n")); + INITUINTOPTION(JpegQuality, Eou(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_JPEG, _T("--jpeg"), 95, SO_REQ_SEP, "\t--jpeg= Jpeg quality 0-100 for compression [default: 95].\n")); + INITUINTOPTION(FirstFrame, Eou(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_BEGIN, _T("--begin"), UINT_MAX, SO_REQ_SEP, "\t--begin= Time of first frame to render [default: first time specified in file].\n")); + INITUINTOPTION(LastFrame, Eou(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_END, _T("--end"), UINT_MAX, SO_REQ_SEP, "\t--end= Time of last frame to render [default: last time specified in the input file].\n")); + INITUINTOPTION(Frame, Eou(eOptionUse::OPT_ANIM_GENOME, eOptionIDs::OPT_FRAME, _T("--frame"), UINT_MAX, SO_REQ_SEP, "\t--frame= Time of first and last frame (ie do one frame).\n")); + INITUINTOPTION(Dtime, Eou(eOptionUse::OPT_USE_ANIMATE, eOptionIDs::OPT_DTIME, _T("--dtime"), 1, SO_REQ_SEP, "\t--dtime= Time between frames [default: 1].\n")); + INITUINTOPTION(Frames, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_NFRAMES, _T("--nframes"), 20, SO_REQ_SEP, "\t--nframes= Number of frames per loop and per interpolation in the animation [default: 20].\n")); + INITUINTOPTION(Repeat, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_REPEAT, _T("--repeat"), 1, SO_REQ_SEP, "\t--repeat= Number of new flames to create. Ignored if sequence, inter or rotate were specified [default: 1].\n")); + INITUINTOPTION(Tries, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_TRIES, _T("--tries"), 10, SO_REQ_SEP, "\t--tries= Number times to try creating a flame that meets the specified constraints. Ignored if sequence, inter or rotate were specified [default: 10].\n")); + INITUINTOPTION(MaxXforms, Eou(eOptionUse::OPT_USE_GENOME, eOptionIDs::OPT_MAX_XFORMS, _T("--maxxforms"), UINT_MAX, SO_REQ_SEP, "\t--maxxforms= The maximum number of xforms allowed in the final output.\n")); //Double. INITDOUBLEOPTION(SizeScale, Eod(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_SS, _T("--ss"), 1, SO_REQ_SEP, "\t--ss= Size scale. All dimensions are scaled by this amount [default: 1.0].\n")); INITDOUBLEOPTION(QualityScale, Eod(eOptionUse::OPT_RENDER_ANIM, eOptionIDs::OPT_QS, _T("--qs"), 1, SO_REQ_SEP, "\t--qs= Quality scale. All quality values are scaled by this amount [default: 1.0].\n")); @@ -473,13 +473,13 @@ public: PARSEUINTOPTION(eOptionIDs::OPT_NTHREADS, ThreadCount);//uint args. PARSEUINTOPTION(eOptionIDs::OPT_STRIPS, Strips); PARSEUINTOPTION(eOptionIDs::OPT_SUPERSAMPLE, Supersample); + PARSEUINTOPTION(eOptionIDs::OPT_TEMPSAMPLES, TemporalSamples); PARSEUINTOPTION(eOptionIDs::OPT_BPC, BitsPerChannel); PARSEUINTOPTION(eOptionIDs::OPT_PRINT_EDIT_DEPTH, PrintEditDepth); PARSEUINTOPTION(eOptionIDs::OPT_JPEG, JpegQuality); PARSEUINTOPTION(eOptionIDs::OPT_BEGIN, FirstFrame); PARSEUINTOPTION(eOptionIDs::OPT_END, LastFrame); PARSEUINTOPTION(eOptionIDs::OPT_FRAME, Frame); - PARSEUINTOPTION(eOptionIDs::OPT_TIME, Time); PARSEUINTOPTION(eOptionIDs::OPT_DTIME, Dtime); PARSEUINTOPTION(eOptionIDs::OPT_NFRAMES, Frames); PARSEUINTOPTION(eOptionIDs::OPT_REPEAT, Repeat); @@ -747,6 +747,7 @@ public: Eou ThreadCount;//Value uint. Eou Strips; Eou Supersample; + Eou TemporalSamples; Eou BitsPerChannel; Eou Bits; Eou PrintEditDepth; @@ -754,7 +755,6 @@ public: Eou FirstFrame; Eou LastFrame; Eou Frame; - Eou Time; Eou Dtime; Eou Frames; Eou Repeat; diff --git a/Source/Fractorium/FractoriumMenus.cpp b/Source/Fractorium/FractoriumMenus.cpp index a3704ca..5820813 100644 --- a/Source/Fractorium/FractoriumMenus.cpp +++ b/Source/Fractorium/FractoriumMenus.cpp @@ -755,15 +755,11 @@ void Fractorium::OnActionAddBothSymmetry(bool checked) { m_Controller->AddBothSy template void FractoriumEmberController::Flatten() { - UpdateXform([&] (Xform* xform) - { - m_Ember.Flatten(XmlToEmber::m_FlattenNames); - FillVariationTreeWithXform(xform); - }, eXformUpdate::UPDATE_CURRENT, false);//Don't update render, it'll update below. UpdateAll([&](Ember& ember) { ember.Flatten(XmlToEmber::m_FlattenNames); }, true, eProcessAction::FULL_RENDER, m_Fractorium->ApplyAll()); + FillVariationTreeWithXform(CurrentXform()); } void Fractorium::OnActionFlatten(bool checked) { m_Controller->Flatten(); } @@ -774,15 +770,11 @@ void Fractorium::OnActionFlatten(bool checked) { m_Controller->Flatten(); } template void FractoriumEmberController::Unflatten() { - UpdateXform([&] (Xform* xform) - { - m_Ember.Unflatten(); - FillVariationTreeWithXform(xform); - }, eXformUpdate::UPDATE_CURRENT, false);//Don't update render, it'll update below. UpdateAll([&](Ember& ember) { ember.Unflatten(); }, true, eProcessAction::FULL_RENDER, m_Fractorium->ApplyAll()); + FillVariationTreeWithXform(CurrentXform()); } void Fractorium::OnActionUnflatten(bool checked) { m_Controller->Unflatten(); }