#include #include #include #include #include #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 "stf_ext.hpp" #include namespace po = boost::program_options; int verbose = 4; std::string generate_filename(){ char filename[64]; time_t t = time(0); struct tm* lt = localtime(&t); sprintf(filename, "attractor_%04d-%02d-%02d_%02d-%02d-%02d", lt->tm_year + 1900, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec); 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); } int main(int argc, char* argv[]) try { std::string attractorFile, output_path; unsigned int iterations, width, height; srand(time(0)); po::options_description desc("Options"); desc.add_options() ("help,h", "produce help message") ("iterations,I", po::value(&iterations)->default_value(DEFAULT_ITERATIONS), "set number of iterations (in milions)") ("width,W", po::value(&width)->default_value(DEFAULT_WIDTH), "width of output image") ("height,H", po::value(&height)->default_value(DEFAULT_HEIGHT), "height of output image") ("input-file,f", po::value(&attractorFile)->default_value(""), "attractor file to read") ("output-path,P", po::value(&output_path)->default_value("render/"), "path to output image") ; po::variables_map vm; po::store(po::parse_command_line(argc, argv, desc), vm); po::notify(vm); if (vm.count("help") || argc <= 1) { //std::cout << desc << std::endl; return 1; } stfu::node stf_input; stf_input.read(attractorFile); std::string filename = output_path + generate_filename(); stfu::node stf_output; Logger logger(std::cout, LOG_VERBOSE); 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(); { 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; } } catch (std::exception & e) { std::cout << "Terminated because of: " << e.what() << std::endl; }