Browse Source

stfu in and output :D (so we can read all those random attractors). some small fixes

master
Joshua Moerman 13 years ago
parent
commit
b47b8f9490
  1. 4
      Attractor.hpp
  2. 8
      AwesomeAttract0r.xcodeproj/project.pbxproj
  3. 2
      Random.hpp
  4. 23
      Tonemapper.hpp
  5. 47
      main.cpp
  6. 55
      stfu/std_string_ext.hpp
  7. 6
      stfu/stf.hpp
  8. 87
      stfu/stf_ext.hpp
  9. 105
      stfu/stf_input.hpp
  10. 85
      stfu/stf_output.hpp

4
Attractor.hpp

@ -26,9 +26,9 @@ public:
LogInfo("Reading file '%s'\n", filename.c_str()); LogInfo("Reading file '%s'\n", filename.c_str());
stfu::node system; stfu::node system;
if(!system.read(filename.c_str())) throw std::runtime_error(filename + " could not be opened"); if(!system.read(filename)) throw std::runtime_error(filename + " could not be opened");
kernel = AttractorKernel::createAttractorKernel(system.getChild("AttractorKernel")); kernel = AttractorKernel::createAttractorKernel(system.getChild("attractor_kernel"));
projector = Projector::createProjector(system.getChild(system.getValue("Projector")), kernel->getDimension()); projector = Projector::createProjector(system.getChild(system.getValue("Projector")), kernel->getDimension());
} }
} }

8
AwesomeAttract0r.xcodeproj/project.pbxproj

@ -63,6 +63,9 @@
427057A81475637B00CBE978 /* ImageFormatBMP.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ImageFormatBMP.hpp; sourceTree = "<group>"; }; 427057A81475637B00CBE978 /* ImageFormatBMP.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ImageFormatBMP.hpp; sourceTree = "<group>"; };
427057A91475637B00CBE978 /* ImageFormatPNG.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ImageFormatPNG.hpp; sourceTree = "<group>"; }; 427057A91475637B00CBE978 /* ImageFormatPNG.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ImageFormatPNG.hpp; sourceTree = "<group>"; };
427057AB1475637B00CBE978 /* Tonemapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tonemapper.hpp; sourceTree = "<group>"; }; 427057AB1475637B00CBE978 /* Tonemapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tonemapper.hpp; sourceTree = "<group>"; };
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 = "<group>"; };
4299F17814B2579B00EDE788 /* stf_input.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = stf_input.hpp; path = stfu/stf_input.hpp; sourceTree = "<group>"; };
4299F17914B2579B00EDE788 /* stf_output.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = stf_output.hpp; path = stfu/stf_output.hpp; sourceTree = "<group>"; };
42CEC38414AB797200C3AEDA /* Random.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Random.hpp; sourceTree = "<group>"; }; 42CEC38414AB797200C3AEDA /* Random.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Random.hpp; sourceTree = "<group>"; };
42CEC38614ABB85200C3AEDA /* stf_ext.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = stf_ext.hpp; path = stfu/stf_ext.hpp; sourceTree = "<group>"; }; 42CEC38614ABB85200C3AEDA /* stf_ext.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = stf_ext.hpp; path = stfu/stf_ext.hpp; sourceTree = "<group>"; };
42CEC38714ABC2C000C3AEDA /* UnravelHeart3D.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = UnravelHeart3D.hpp; path = kernels/UnravelHeart3D.hpp; sourceTree = "<group>"; }; 42CEC38714ABC2C000C3AEDA /* UnravelHeart3D.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = UnravelHeart3D.hpp; path = kernels/UnravelHeart3D.hpp; sourceTree = "<group>"; };
@ -84,9 +87,12 @@
01C5709C13B63E2F009D151B /* stf */ = { 01C5709C13B63E2F009D151B /* stf */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
4299F17414B256F700EDE788 /* std_string_ext.hpp */,
01C5703013B63B78009D151B /* stf.hpp */, 01C5703013B63B78009D151B /* stf.hpp */,
42CEC38614ABB85200C3AEDA /* stf_ext.hpp */,
01C5703113B63B78009D151B /* stf.cpp */, 01C5703113B63B78009D151B /* stf.cpp */,
4299F17814B2579B00EDE788 /* stf_input.hpp */,
4299F17914B2579B00EDE788 /* stf_output.hpp */,
42CEC38614ABB85200C3AEDA /* stf_ext.hpp */,
); );
name = stf; name = stf;
sourceTree = "<group>"; sourceTree = "<group>";

2
Random.hpp

@ -20,7 +20,7 @@ namespace Random {
All uniform distributions are inclusive (ie [min, max]). All uniform distributions are inclusive (ie [min, max]).
*/ */
template <typename T> template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value && !std::is_integral<T>::value, T>::type uniform(T min, T max){ typename std::enable_if<std::is_arithmetic<T>::value && std::is_floating_point<T>::value, T>::type uniform(T min, T max){
return min + (rand() / (T) RAND_MAX) * (max - min); return min + (rand() / (T) RAND_MAX) * (max - min);
} }

23
Tonemapper.hpp

@ -91,6 +91,12 @@ namespace Tonemappers {
, colors({{Random::make_vector(-2.0, 4.0, n_planes), Random::make_vector(-2.0, 4.0, n_planes), Random::make_vector(-2.0, 4.0, n_planes)}}) , colors({{Random::make_vector(-2.0, 4.0, n_planes), Random::make_vector(-2.0, 4.0, n_planes), Random::make_vector(-2.0, 4.0, n_planes)}})
{} {}
Colorizer(size_t n_planes, stfu::node const & n)
: gamma_correctors(n_planes)
, gammas(stfu::from_stf<Matrix>(n.getChild("gamma_matrix")))
, colors(stfu::from_stf<Matrix>(n.getChild("color_matrix")))
{}
template <typename C> template <typename C>
void analyse(C const & canvas){ void analyse(C const & canvas){
for (size_t i = 0; i < gamma_correctors.size(); ++i) { for (size_t i = 0; i < gamma_correctors.size(); ++i) {
@ -131,10 +137,23 @@ namespace Tonemappers {
return node; return node;
} }
static Colorizer from_stf(stfu::node const & n) {
if (n.getValue("class") != "colorizer") std::cerr << "trying to read an stf as colorizer whil class != \"colorizer\"";
auto g = stfu::from_stf<Matrix>(n.getChild("gamma_matrix"));
auto c = stfu::from_stf<Matrix>(n.getChild("color_matrix"));
Colorizer tonemapper(g[0].size());
tonemapper.gammas = g;
tonemapper.colors = c;
return tonemapper;
}
protected: protected:
std::vector<GammaCorrector> gamma_correctors; std::vector<GammaCorrector> gamma_correctors;
std::array<std::vector<double>, 3> gammas; typedef std::array<std::vector<double>, 3> Matrix;
std::array<std::vector<double>, 3> colors; Matrix gammas;
Matrix colors;
}; };
} }

47
main.cpp

@ -54,6 +54,16 @@ void render(Attractor & myAttractor, C & canvas, unsigned int iterations){
} }
} }
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 { int main(int argc, char* argv[]) try {
std::string attractorFile, output_path; std::string attractorFile, output_path;
unsigned int iterations, width, height; unsigned int iterations, width, height;
@ -74,14 +84,18 @@ int main(int argc, char* argv[]) try {
po::notify(vm); po::notify(vm);
if (vm.count("help") || argc <= 1) { if (vm.count("help") || argc <= 1) {
std::cout << desc << std::endl; //std::cout << desc << std::endl;
return 1; return 1;
} }
stfu::node stf_input;
stf_input.read(attractorFile);
std::string filename = output_path + generate_filename(); std::string filename = output_path + generate_filename();
stfu::node output; stfu::node stf_output;
Logger logger(std::cout, LOG_VERBOSE); Logger logger(std::cout, LOG_VERBOSE);
LayeredCanvas<Canvas2D<unsigned int> > canvas(width, height, 2); LayeredCanvas<Canvas2D<unsigned int> > canvas(width, height, 2);
{ {
Attractor my_attractor(attractorFile); Attractor my_attractor(attractorFile);
@ -97,26 +111,29 @@ int main(int argc, char* argv[]) try {
return 0; return 0;
} }
output = stfu::to_stf(my_attractor); stf_output = stfu::to_stf(my_attractor);
} }
{
Tonemappers::Colorizer tonemapper(canvas.layers(), Random::parameters());
tonemapper.analyse(canvas);
logger.start("saving image");
ImageFormats::png::png_stream image(canvas.size<0>(), canvas.size<1>(), filename + ".png");
tonemapper.process(canvas, image);
logger.stop();
output.addChild("tonemapper") = stfu::to_stf(tonemapper); 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();
{ {
output.addValue("version") = __DATE__" "__TIME__; stf_output.addValue("version") = __DATE__" "__TIME__;
output.addValue("notes") = "This is the version with `cheap` blur and random colours"; stf_output.addValue("notes") = "This is the version with `cheap` blur and random colours";
std::string path(filename + ".stf"); std::string path(filename + ".stf");
std::ofstream file(path.c_str()); std::ofstream file(path.c_str());
file << output << std::endl; file << stf_output << std::endl;
} }
} catch (std::exception & e) { } catch (std::exception & e) {
std::cout << "Terminated because of: " << e.what() << std::endl; std::cout << "Terminated because of: " << e.what() << std::endl;

55
stfu/std_string_ext.hpp

@ -0,0 +1,55 @@
//
// std_string_ext.hpp
// AwesomeAttract0r
//
// Created by Joshua Moerman on 1/2/12.
// Copyright (c) 2012 Vadovas. All rights reserved.
//
#ifndef AwesomeAttract0r_std_string_ext_hpp
#define AwesomeAttract0r_std_string_ext_hpp
namespace std {
template <typename T>
std::string to_string(T const & x){
std::stringstream ss;
ss << x;
return ss.str();
}
namespace {
template <typename T>
struct from_string_struct {
T operator()(string const & s){
stringstream ss(s);
T t;
ss >> t;
return t;
}
};
#define from_string_fund(x, y) \
template <> \
struct from_string_struct<x> { \
x operator()(string const & s){ return y(s); } \
};
from_string_fund(float, stof)
from_string_fund(double, stod)
from_string_fund(long double, stold)
from_string_fund(int, stoi)
from_string_fund(long int, stol)
from_string_fund(long unsigned int, stoul)
from_string_fund(long long int, stoll)
from_string_fund(long long unsigned int, stoull)
from_string_fund(string, )
#undef from_string_fund
} // namespace
template <typename T>
T from_string(string const & s){
return from_string_struct<T>()(s);
}
}
#endif

6
stfu/stf.hpp

@ -106,7 +106,7 @@ public:
\param index If there are > 1 values with the same name, they are indexed. Here you can supply an indexnumber. \param index If there are > 1 values with the same name, they are indexed. Here you can supply an indexnumber.
\return Returns a const std::string& to the value of value with the name and index specified \return Returns a const std::string& to the value of value with the name and index specified
*/ */
const std::string& getValue(const std::string& name, size_t index) const throw(std::out_of_range); const std::string& getValue(const std::string& name, size_t index = 0) const throw(std::out_of_range);
/** /**
Same as getValue() const, but for unnamed values Same as getValue() const, but for unnamed values
@ -280,6 +280,10 @@ public:
*/ */
bool read(const char* filename); bool read(const char* filename);
bool read(std::string const & str){
return read(str.c_str());
}
/** /**
Writes the STF to an ostream with optional indentation Writes the STF to an ostream with optional indentation
\param out ostream to write to \param out ostream to write to

87
stfu/stf_ext.hpp

@ -9,91 +9,8 @@
#ifndef AwesomeAttract0r_stf_ext_hpp #ifndef AwesomeAttract0r_stf_ext_hpp
#define AwesomeAttract0r_stf_ext_hpp #define AwesomeAttract0r_stf_ext_hpp
#include <sstream>
#include <list>
#include <vector>
#include <array>
#include "stf.hpp" #include "stf.hpp"
#include "stf_input.hpp"
namespace std { #include "stf_output.hpp"
template <typename T>
std::string to_string(T const & x){
std::stringstream ss;
ss << x;
return ss.str();
}
}
namespace stfu {
// Prototypes
#define to_stf_container_proto(x) \
template <typename T> \
typename std::enable_if<std::is_fundamental<T>::value, node>::type to_stf(x<T> const & array); \
template <typename T> \
typename std::enable_if<!std::is_fundamental<T>::value, node>::type to_stf(x<T> const & array);
to_stf_container_proto(std::vector)
to_stf_container_proto(std::list)
#undef to_stf_container_proto
template <typename T, size_t N>
typename std::enable_if<std::is_fundamental<T>::value, node>::type to_stf(std::array<T, N> const & array);
template <typename T, size_t N>
typename std::enable_if<!std::is_fundamental<T>::value, node>::type to_stf(std::array<T, N> const & array);
template <typename T>
node to_stf(T const & x);
// implementations
#define to_stf_container(x) \
template <typename T> \
typename std::enable_if<std::is_fundamental<T>::value, node>::type to_stf(x<T> const & array) { \
node node; \
for (auto it = array.cbegin(); it != array.cend(); ++it){ \
node.addValue() = std::to_string(*it); \
} \
return node; \
} \
\
template <typename T> \
typename std::enable_if<!std::is_fundamental<T>::value, node>::type to_stf(x<T> const & array) { \
node node; \
for (auto it = array.cbegin(); it != array.cend(); ++it){ \
node.addChild() = to_stf(*it); \
} \
return node; \
}
to_stf_container(std::vector)
to_stf_container(std::list)
#undef to_stf_container
template <typename T, size_t N>
typename std::enable_if<std::is_fundamental<T>::value, node>::type to_stf(std::array<T, N> const & array) {
node node;
for (auto it = array.cbegin(); it != array.cend(); ++it){
node.addValue() = std::to_string(*it);
}
return node;
}
template <typename T, size_t N>
typename std::enable_if<!std::is_fundamental<T>::value, node>::type to_stf(std::array<T, N> const & array) {
node node;
for (auto it = array.cbegin(); it != array.cend(); ++it){
node.addChild() = to_stf(*it);
}
return node;
}
template <typename T>
node to_stf(T const & x){
return x.to_stf();
}
} // namespace stfu
#endif #endif

105
stfu/stf_input.hpp

@ -0,0 +1,105 @@
//
// stf_input.hpp
// AwesomeAttract0r
//
// Created by Joshua Moerman on 1/2/12.
// Copyright (c) 2012 Vadovas. All rights reserved.
//
#ifndef AwesomeAttract0r_stf_input_hpp
#define AwesomeAttract0r_stf_input_hpp
#include <sstream>
#include <vector>
#include <array>
#include "stf.hpp"
#include "std_string_ext.hpp"
namespace stfu {
// prototypes
template <typename T>
T from_stf(node const & n);
// implemtations
namespace {
template <typename T, typename Enable = void>
struct from_stf_struct {
T operator()(node const & n){
return T::from_stf(n);
}
};
template <typename T>
struct from_stf_struct<std::vector<T>, typename std::enable_if<!std::is_fundamental<T>::value>::type>;
template <typename T>
struct from_stf_struct<std::vector<T>, typename std::enable_if<std::is_fundamental<T>::value>::type>;
template <typename T, size_t N>
struct from_stf_struct<std::array<T, N>, typename std::enable_if<!std::is_fundamental<T>::value>::type>;
template <typename T, size_t N>
struct from_stf_struct<std::array<T, N>, typename std::enable_if<std::is_fundamental<T>::value>::type>;
template <typename T>
struct from_stf_struct<std::vector<T>, typename std::enable_if<!std::is_fundamental<T>::value>::type>{
std::vector<T> operator()(node const & n){
std::vector<T> v;
bool done = false;
for(unsigned int i = 0; !done; ++i){
try {
v.push_back(from_stf<T>(n.getChild(i)));
} catch (std::out_of_range& e) {
done = true;
}
}
return v;
}
};
template <typename T>
struct from_stf_struct<std::vector<T>, typename std::enable_if<std::is_fundamental<T>::value>::type>{
std::vector<T> operator()(node const & n){
std::vector<T> v;
bool done = false;
for(unsigned int i = 0; !done; ++i){
try {
v.push_back(std::from_string<T>(n.getValue(i)));
} catch (std::out_of_range& e) {
done = true;
}
}
return v;
}
};
template <typename T, size_t N>
struct from_stf_struct<std::array<T, N>, typename std::enable_if<!std::is_fundamental<T>::value>::type>{
std::array<T, N> operator()(node const & n){
std::array<T, N> v;
for(unsigned int i = 0; i < N; ++i){
v[i] = from_stf<T>(n.getChild(i));
}
return v;
}
};
template <typename T, size_t N>
struct from_stf_struct<std::array<T, N>, typename std::enable_if<std::is_fundamental<T>::value>::type>{
std::array<T, N> operator()(node const & n){
std::array<T, N> v;
for(unsigned int i = 0; i < N; ++i){
v[i] = std::from_string<T>(n.getValue(i));
}
return v;
}
};
}
template <typename T>
T from_stf(node const & n){
return from_stf_struct<T>()(n);
}
} // namespace stfu
#endif

85
stfu/stf_output.hpp

@ -0,0 +1,85 @@
//
// stf_output.hpp
// AwesomeAttract0r
//
// Created by Joshua Moerman on 1/2/12.
// Copyright (c) 2012 Vadovas. All rights reserved.
//
#ifndef AwesomeAttract0r_stf_output_hpp
#define AwesomeAttract0r_stf_output_hpp
#include <sstream>
#include <vector>
#include <array>
#include "stf.hpp"
#include "std_string_ext.hpp"
namespace stfu {
// Prototypes
#define to_stf_container_proto(x) \
template <typename T> \
typename std::enable_if<std::is_fundamental<T>::value, node>::type to_stf(x<T> const & array); \
template <typename T> \
typename std::enable_if<!std::is_fundamental<T>::value, node>::type to_stf(x<T> const & array);
to_stf_container_proto(std::vector)
#undef to_stf_container_proto
template <typename T, size_t N>
typename std::enable_if<std::is_fundamental<T>::value, node>::type to_stf(std::array<T, N> const & array);
template <typename T, size_t N>
typename std::enable_if<!std::is_fundamental<T>::value, node>::type to_stf(std::array<T, N> const & array);
template <typename T>
node to_stf(T const & x);
// implementations
#define to_stf_container(x) \
template <typename T> \
typename std::enable_if<std::is_fundamental<T>::value, node>::type to_stf(x<T> const & array) { \
node node; \
for (auto it = array.cbegin(); it != array.cend(); ++it) \
node.addValue() = std::to_string(*it); \
return node; \
} \
\
template <typename T> \
typename std::enable_if<!std::is_fundamental<T>::value, node>::type to_stf(x<T> const & array) { \
node node; \
for (auto it = array.cbegin(); it != array.cend(); ++it) \
node.addChild() = to_stf(*it); \
return node; \
}
to_stf_container(std::vector)
#undef to_stf_container
template <typename T, size_t N>
typename std::enable_if<std::is_fundamental<T>::value, node>::type to_stf(std::array<T, N> const & array) {
node node;
for (auto it = array.cbegin(); it != array.cend(); ++it){
node.addValue() = std::to_string(*it);
}
return node;
}
template <typename T, size_t N>
typename std::enable_if<!std::is_fundamental<T>::value, node>::type to_stf(std::array<T, N> const & array) {
node node;
for (auto it = array.cbegin(); it != array.cend(); ++it){
node.addChild() = to_stf(*it);
}
return node;
}
template <typename T>
node to_stf(T const & x){
return x.to_stf();
}
} // namespace stfu
#endif