You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
4.2 KiB
143 lines
4.2 KiB
#include <iostream>
|
|
#include <fstream>
|
|
#include <ctime>
|
|
#include <cstring>
|
|
#include <cstdlib>
|
|
|
|
#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 <boost/program_options.hpp>
|
|
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 <typename C>
|
|
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 <typename C, typename TM>
|
|
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<unsigned int>(&iterations)->default_value(DEFAULT_ITERATIONS), "set number of iterations (in milions)")
|
|
("width,W", po::value<unsigned int>(&width)->default_value(DEFAULT_WIDTH), "width of output image")
|
|
("height,H", po::value<unsigned int>(&height)->default_value(DEFAULT_HEIGHT), "height of output image")
|
|
("input-file,f", po::value<std::string>(&attractorFile)->default_value(""), "attractor file to read")
|
|
("output-path,P", po::value<std::string>(&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<Canvas2D<unsigned int> > 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;
|
|
}
|
|
|
|
|
|
|
|
|