From c0938378f1cd5cfffd944a5900729aec38618adb Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Mon, 9 Jan 2012 10:08:47 +0100 Subject: [PATCH] shorter main --- AwesomeAttract0r.xcodeproj/project.pbxproj | 4 + Logger.hpp | 7 +- Random.hpp | 7 ++ attractors/emptyUnravel3D.stf | 2 +- main.cpp | 101 ++++----------------- output.hpp | 48 ++++++++++ projectors/Normalizer.cpp | 1 - render.hpp | 62 +++++++++++++ stfu/stf.hpp | 8 ++ 9 files changed, 154 insertions(+), 86 deletions(-) create mode 100644 output.hpp create mode 100644 render.hpp diff --git a/AwesomeAttract0r.xcodeproj/project.pbxproj b/AwesomeAttract0r.xcodeproj/project.pbxproj index 7a3c13e..d3e5b0d 100644 --- a/AwesomeAttract0r.xcodeproj/project.pbxproj +++ b/AwesomeAttract0r.xcodeproj/project.pbxproj @@ -63,6 +63,8 @@ 427057A81475637B00CBE978 /* ImageFormatBMP.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ImageFormatBMP.hpp; sourceTree = ""; }; 427057A91475637B00CBE978 /* ImageFormatPNG.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ImageFormatPNG.hpp; sourceTree = ""; }; 427057AB1475637B00CBE978 /* Tonemapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tonemapper.hpp; sourceTree = ""; }; + 428981DD14BA1D72000C437F /* output.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = output.hpp; sourceTree = ""; }; + 428981DF14BA1EB1000C437F /* render.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = render.hpp; sourceTree = ""; }; 4299F17414B256F700EDE788 /* std_string_ext.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = std_string_ext.hpp; path = stfu/std_string_ext.hpp; sourceTree = ""; }; 4299F17814B2579B00EDE788 /* stf_input.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = stf_input.hpp; path = stfu/stf_input.hpp; sourceTree = ""; }; 4299F17914B2579B00EDE788 /* stf_output.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = stf_output.hpp; path = stfu/stf_output.hpp; sourceTree = ""; }; @@ -144,6 +146,8 @@ 01C5701013B63AF0009D151B /* Attractor.hpp */, 01C5701113B63AF0009D151B /* Attractor.cpp */, 08FB7796FE84155DC02AAC07 /* main.cpp */, + 428981DF14BA1EB1000C437F /* render.hpp */, + 428981DD14BA1D72000C437F /* output.hpp */, ); name = Source; sourceTree = ""; diff --git a/Logger.hpp b/Logger.hpp index c59c9b0..2eacfae 100644 --- a/Logger.hpp +++ b/Logger.hpp @@ -146,7 +146,7 @@ struct Progressbar : public LoggingBase { ~Progressbar(){ if (shouldSkip()) return; - show(1, 1, '='); + if (!std::uncaught_exception()) show(1, 1, '='); out << std::endl; } @@ -188,7 +188,8 @@ struct ProgressIndicator : public LoggingBase { } ~ProgressIndicator(){ - show("="); + if (shouldSkip()) return; + if (!std::uncaught_exception()) show("="); out << std::endl; } @@ -227,5 +228,7 @@ private: unsigned int progress; }; +extern Logger logger; + #endif // LOGGER_HPP_INCLUDED diff --git a/Random.hpp b/Random.hpp index 5f87e37..81b10d4 100644 --- a/Random.hpp +++ b/Random.hpp @@ -38,6 +38,13 @@ namespace Random { return ret; } + template + std::pair in_circle(T radius){ + T r = uniform(0, radius); + T t = uniform(-M_PI, M_PI); + return std::make_pair(r * std::cos(t), r * std::sin(t)); + } + } // namespace random #endif diff --git a/attractors/emptyUnravel3D.stf b/attractors/emptyUnravel3D.stf index af11b63..a775b55 100644 --- a/attractors/emptyUnravel3D.stf +++ b/attractors/emptyUnravel3D.stf @@ -1,4 +1,4 @@ -AttractorKernel: { +attractor_kernel: { type: "unravel" dimensions: "3" } diff --git a/main.cpp b/main.cpp index 4a8a215..f07499e 100644 --- a/main.cpp +++ b/main.cpp @@ -3,25 +3,22 @@ #include #include #include +#include +namespace po = boost::program_options; +#include "stf.hpp" #include "Logger.hpp" -#include "ostream_helpers.h" #include "defines.hpp" #include "AwesomeAttractorConfig.h" -#include "Attractor.hpp" -#include "Canvas.hpp" -#include "Image.hpp" -#include "Tonemapper.hpp" #include "Random.hpp" +#include "Canvas.hpp" +#include "output.hpp" +#include "render.hpp" -#include "stf_ext.hpp" - -#include -namespace po = boost::program_options; int verbose = 4; - +Logger logger(std::cout, LOG_VERBOSE); std::string generate_filename(){ char filename[64]; @@ -32,36 +29,12 @@ std::string generate_filename(){ return std::string(filename); } -template -void render(Attractor & myAttractor, C & canvas, unsigned int iterations){ - Progressbar progress(std::cout, LOG_INFO, "rendering"); - for(unsigned int j = 1; j <= iterations; ++j) { - for(unsigned int i = 0; i < 1000000; ++i) { - myAttractor.iterate(); - myAttractor.project(); - canvas.plot(myAttractor.projector->projectedPoint, 0); - double x = rand() / (double) RAND_MAX - 0.5; - double y = rand() / (double) RAND_MAX - 0.5; - x *= x*x; - y *= y*y; - double blur[2] = {myAttractor.projector->projectedPoint[0] + x*0.3, myAttractor.projector->projectedPoint[1] + y*0.3}; - canvas.plot(blur, 1); - } - progress.show(j, iterations); - if(j == iterations/4) if(!filled(canvas, 0.01)) return; - if(j == iterations/4 * 2) if(!filled(canvas, 0.02)) return; - if(j == iterations/4 * 3) if(!filled(canvas, 0.03)) return; - } -} - -template -void output(C const & canvas, TM & tonemapper, std::string const & image_path, stfu::node & stf_output){ - tonemapper.analyse(canvas); - - ImageFormats::png::png_stream image(canvas.template size<0>(), canvas.template size<1>(), image_path + ".png"); - tonemapper.process(canvas, image); - - stf_output.addChild("tonemapper") = stfu::to_stf(tonemapper); +void save_stf(stfu::node & stf_output, std::string const & filename){ + stf_output.addValue("version") = __DATE__" "__TIME__; + stf_output.addValue("notes") = "This is the version with `cheap` blur and random colours"; + std::string path(filename + ".stf"); + std::ofstream file(path.c_str()); + file << stf_output << std::endl; } int main(int argc, char* argv[]) try { @@ -88,53 +61,17 @@ int main(int argc, char* argv[]) try { return 1; } - stfu::node stf_input; + stfu::node stf_input, stf_output; stf_input.read(attractorFile); - std::string filename = output_path + generate_filename(); - stfu::node stf_output; - Logger logger(std::cout, LOG_VERBOSE); - - + std::string filename = output_path + generate_filename(); LayeredCanvas > canvas(width, height, 2); - { - Attractor my_attractor(attractorFile); - - my_attractor.init_range(); - - logger.start("rendering"); - render(my_attractor, canvas, iterations); - logger.stop(); - - if(!filled(canvas, 0.04)){ - logger.log("The canvas is too empty. Stopping."); - return 0; - } - - stf_output = stfu::to_stf(my_attractor); - } - - - - logger.start("analysing canvas and saving image"); - if(stf_input.getChild("tonemapper").getValue("class") == "colorizer") { - Tonemappers::Colorizer tonemapper(canvas.layers(), stf_input.getChild("tonemapper")); - output(canvas, tonemapper, filename, stf_output); - } else { - Tonemappers::Colorizer tonemapper(canvas.layers(), Random::parameters()); - output(canvas, tonemapper, filename, stf_output); - } - logger.stop(); + render(canvas, attractorFile, stf_output, iterations); + if(stf_input.childExists("tonemapper")) output(canvas, stf_input.getChild("tonemapper"), filename, stf_output); + else output(canvas, Random::parameters(), filename, stf_output); - - { - stf_output.addValue("version") = __DATE__" "__TIME__; - stf_output.addValue("notes") = "This is the version with `cheap` blur and random colours"; - std::string path(filename + ".stf"); - std::ofstream file(path.c_str()); - file << stf_output << std::endl; - } + save_stf(stf_output, filename); } catch (std::exception & e) { std::cout << "Terminated because of: " << e.what() << std::endl; } diff --git a/output.hpp b/output.hpp new file mode 100644 index 0000000..a4506f9 --- /dev/null +++ b/output.hpp @@ -0,0 +1,48 @@ +// +// output.hpp +// AwesomeAttract0r +// +// Created by Joshua Moerman on 1/8/12. +// Copyright (c) 2012 Vadovas. All rights reserved. +// + +#ifndef AwesomeAttract0r_output_hpp +#define AwesomeAttract0r_output_hpp + +#include "Logger.hpp" +#include "stf.hpp" +#include "Random.hpp" +#include "Image.hpp" +#include "Tonemapper.hpp" + +namespace details { + template + void output(C const & canvas, TM & tonemapper, std::string const & image_path, stfu::node & stf_output){ + logger.start("Analysing"); + tonemapper.analyse(canvas); + logger.stop(); + + ImageFormats::png::png_stream image(canvas.template size<0>(), canvas.template size<1>(), image_path + ".png"); + logger.start("Exporting"); + tonemapper.process(canvas, image); + logger.stop(); + + stf_output.addChild("tonemapper") = stfu::to_stf(tonemapper); + } +} + +template +void output(C const & canvas, stfu::node const & stf_input, std::string const & filename, stfu::node & stf_output){ + if(stf_input.getValue("class") == "colorizer") { + Tonemappers::Colorizer tonemapper(canvas.layers(), stf_input); + details::output(canvas, tonemapper, filename, stf_output); + } +} + +template +void output(C const & canvas, Random::parameters, std::string const & filename, stfu::node & stf_output) { + Tonemappers::Colorizer tonemapper(canvas.layers(), Random::parameters()); + details::output(canvas, tonemapper, filename, stf_output); +} + +#endif diff --git a/projectors/Normalizer.cpp b/projectors/Normalizer.cpp index 5f43364..8f69d4a 100644 --- a/projectors/Normalizer.cpp +++ b/projectors/Normalizer.cpp @@ -50,7 +50,6 @@ void Normalizer::project(const double* point) { for(unsigned int i = 0; i < inputDimension; ++i) { projectedPoint[i] = point[i]*factor + offset[i]; } - projectedColor[0] = sin(2.0 * point[2]); if(!ready) { static unsigned int state = 0; diff --git a/render.hpp b/render.hpp new file mode 100644 index 0000000..9a10f8b --- /dev/null +++ b/render.hpp @@ -0,0 +1,62 @@ +// +// render.hpp +// AwesomeAttract0r +// +// Created by Joshua Moerman on 1/8/12. +// Copyright (c) 2012 Vadovas. All rights reserved. +// + +#ifndef AwesomeAttract0r_render_hpp +#define AwesomeAttract0r_render_hpp + +#include + +#include "stf.hpp" +#include "Logger.hpp" +#include "Random.hpp" +#include "Attractor.hpp" + +namespace details { + struct empty_canvas : public std::runtime_error { + empty_canvas() + : std::runtime_error("Canvas is too empty (no chaos)") + { } + }; + + template + void render(Attractor & myAttractor, C & canvas, unsigned int iterations){ + Progressbar progress(std::cout, LOG_INFO, "rendering"); + for(unsigned int j = 1; j <= iterations; ++j) { + for(unsigned int i = 0; i < 1000000; ++i) { + myAttractor.iterate(); + myAttractor.project(); + canvas.plot(myAttractor.projector->projectedPoint, 0); + auto c = Random::in_circle(0.3); + double blur[2] = {myAttractor.projector->projectedPoint[0] + c.first, myAttractor.projector->projectedPoint[1] + c.second}; + canvas.plot(blur, 1); + } + progress.show(j, iterations); + if(j == iterations/4) if(!filled(canvas, 0.01)) throw empty_canvas(); + if(j == iterations/4 * 2) if(!filled(canvas, 0.02)) throw empty_canvas(); + if(j == iterations/4 * 3) if(!filled(canvas, 0.03)) throw empty_canvas(); + } + } +} + +template +void render(C & canvas, std::string const & attractorFile, stfu::node & stf_output, unsigned int iterations) { + Attractor my_attractor(attractorFile); + + my_attractor.init_range(); + + logger.start("rendering"); + details::render(my_attractor, canvas, iterations); + logger.stop(); + + if(!filled(canvas, 0.04)) + throw details::empty_canvas(); + + stf_output = stfu::to_stf(my_attractor); +} + +#endif diff --git a/stfu/stf.hpp b/stfu/stf.hpp index e485c46..8252c9f 100644 --- a/stfu/stf.hpp +++ b/stfu/stf.hpp @@ -67,6 +67,14 @@ public: //@} node() : values(), children() {} + + bool childExists(const std::string & str, size_t index = 0){ + return children.count(str) >= (index + 1); + } + + bool valueExists(const std::string & str, size_t index = 0){ + return values.count(str) >= (index + 1); + } /** Clears the whole node recursively.