Support layer and interaction transparancy. Refs #1

This commit is contained in:
2018-04-05 16:08:58 +02:00
parent 21fdc45e65
commit 3e4452ca3a
12 changed files with 114 additions and 12 deletions

View File

@@ -58,6 +58,8 @@ ActivityAnimation::ActivityAnimation(
lineIndices.push_back(i); lineIndices.push_back(i);
lineIndices.push_back(i + interactions.size()); lineIndices.push_back(i + interactions.size());
} }
patchTransparancy(colorBuf.begin(), colorBuf.end());
} }
void ActivityAnimation::draw(float timeScale) void ActivityAnimation::draw(float timeScale)

View File

@@ -1,5 +1,7 @@
//
// Created by bert on 13/02/18.
//
#include "Animation.hpp" #include "Animation.hpp"
#include "RenderingState.hpp"
float fmri::Animation::getAlpha()
{
return fmri::RenderingState::instance().interactionAlpha();
}

View File

@@ -1,6 +1,8 @@
#pragma once #pragma once
#include "utils.hpp"
namespace fmri namespace fmri
{ {
class Animation class Animation
@@ -10,5 +12,21 @@ namespace fmri
virtual void draw(float step) = 0; virtual void draw(float step) = 0;
private:
static float getAlpha();
protected:
template<typename It>
void patchTransparancy(It begin, It end)
{
if constexpr (std::tuple_size<Color>::value >= 4) {
const auto alpha = getAlpha();
for (; begin != end; ++begin) {
Color &color = *begin;
color[3] = alpha;
}
}
}
}; };
} }

View File

@@ -68,6 +68,8 @@ FlatLayerVisualisation::FlatLayerVisualisation(const LayerData &layer, Ordering
assert(indexPos == indexBuffer.end()); assert(indexPos == indexBuffer.end());
assert(colorPos == colorBuffer.end()); assert(colorPos == colorBuffer.end());
patchTransparancy(colorBuffer.begin(), colorBuffer.end());
} }
void FlatLayerVisualisation::render() void FlatLayerVisualisation::render()

View File

@@ -1,6 +1,7 @@
#include "LayerVisualisation.hpp" #include "LayerVisualisation.hpp"
#include "Range.hpp" #include "Range.hpp"
#include "utils.hpp" #include "utils.hpp"
#include "RenderingState.hpp"
const std::vector<float> &fmri::LayerVisualisation::nodePositions() const const std::vector<float> &fmri::LayerVisualisation::nodePositions() const
{ {
@@ -25,6 +26,11 @@ void fmri::LayerVisualisation::initNodePositions<fmri::LayerVisualisation::Order
} }
} }
float fmri::LayerVisualisation::getAlpha()
{
return RenderingState::instance().layerAlpha();
}
template<> template<>
void fmri::LayerVisualisation::initNodePositions<fmri::LayerVisualisation::Ordering::SQUARE>(size_t n, float spacing) void fmri::LayerVisualisation::initNodePositions<fmri::LayerVisualisation::Ordering::SQUARE>(size_t n, float spacing)
{ {

View File

@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include "utils.hpp"
namespace fmri namespace fmri
{ {
@@ -19,10 +20,25 @@ namespace fmri
virtual void render() = 0; virtual void render() = 0;
virtual const std::vector<float>& nodePositions() const; virtual const std::vector<float>& nodePositions() const;
private:
static float getAlpha();
protected: protected:
std::vector<float> nodePositions_; std::vector<float> nodePositions_;
template<Ordering Order> template<Ordering Order>
void initNodePositions(size_t n, float spacing); void initNodePositions(size_t n, float spacing);
template<typename It>
void patchTransparancy(It begin, It end)
{
if constexpr (std::tuple_size<Color>::value >= 4) {
const auto alpha = getAlpha();
for (; begin != end; ++begin) {
Color &color = *begin;
color[3] = alpha;
}
}
}
}; };
} }

View File

@@ -70,6 +70,8 @@ Options Options::parse(const int argc, char *const argv[])
("labels,l", value<std::string>(&options.labelsPath), "labels file") ("labels,l", value<std::string>(&options.labelsPath), "labels file")
("means,m", value<std::string>(&options.meansPath), "means file") ("means,m", value<std::string>(&options.meansPath), "means file")
("path-color,p", value<std::string>(), "color for paths") ("path-color,p", value<std::string>(), "color for paths")
("layer-opacity", value<float>(&options.layerTransparancy_), "Opacity for layers")
("interaction-opacity", value<float>(&options.interactionTransparancy_), "Opacity for interactions")
("dump,d", value<std::string>(&options.dumpPath), "dump convolutional images in this directory"); ("dump,d", value<std::string>(&options.dumpPath), "dump convolutional images in this directory");
options_description composed = desc; options_description composed = desc;
@@ -92,12 +94,12 @@ Options Options::parse(const int argc, char *const argv[])
// Sanity checks // Sanity checks
check_file(options.modelPath); check_file(options.modelPath);
check_file(options.weightsPath); check_file(options.weightsPath);
check_file(options.meansPath); if (!options.meansPath.empty()) check_file(options.meansPath);
if (!options.labelsPath.empty()) check_file(options.labelsPath);
std::for_each(options.inputPaths.begin(), options.inputPaths.end(), check_file); std::for_each(options.inputPaths.begin(), options.inputPaths.end(), check_file);
return options; return options;
} catch (required_option& e) { } catch (required_option& e) {
std::cerr << e.get_option_name() << std::endl;
if (e.get_option_name() == "--input") { if (e.get_option_name() == "--input") {
std::cerr << "No input files specified" << std::endl; std::cerr << "No input files specified" << std::endl;
} else { } else {
@@ -149,6 +151,8 @@ std::optional<PNGDumper> Options::imageDumper() const
} }
Options::Options() noexcept : Options::Options() noexcept :
layerTransparancy_(1),
interactionTransparancy_(1),
pathColor_({1, 1, 1, 0.1}) pathColor_({1, 1, 1, 0.1})
{ {
} }
@@ -157,3 +161,13 @@ const Color &Options::pathColor() const
{ {
return pathColor_; return pathColor_;
} }
float Options::layerTransparancy() const
{
return layerTransparancy_;
}
float Options::interactionTransparancy() const
{
return interactionTransparancy_;
}

View File

@@ -22,10 +22,14 @@ namespace fmri {
const Color& pathColor() const; const Color& pathColor() const;
std::optional<vector<string>> labels() const; std::optional<vector<string>> labels() const;
std::optional<fmri::PNGDumper> imageDumper() const; std::optional<fmri::PNGDumper> imageDumper() const;
float layerTransparancy() const;
float interactionTransparancy() const;
const vector<string>& inputs() const; const vector<string>& inputs() const;
private: private:
float layerTransparancy_;
float interactionTransparancy_;
Color pathColor_; Color pathColor_;
string modelPath; string modelPath;
string weightsPath; string weightsPath;

View File

@@ -341,9 +341,11 @@ bool RenderingState::renderInteractionPaths() const
return options.renderInteractionPaths; return options.renderInteractionPaths;
} }
void RenderingState::loadOptions(const Options &options) void RenderingState::loadOptions(const Options &programOptions)
{ {
this->options.pathColor = options.pathColor(); options.pathColor = programOptions.pathColor();
options.layerAlpha = programOptions.layerTransparancy();
options.interactionAlpha = programOptions.interactionTransparancy();
} }
const Color &RenderingState::pathColor() const const Color &RenderingState::pathColor() const
@@ -369,3 +371,13 @@ RenderingState::RenderingState() noexcept
// Set initial point size // Set initial point size
glPointSize(3); glPointSize(3);
} }
float RenderingState::interactionAlpha() const
{
return options.interactionAlpha;
}
float RenderingState::layerAlpha() const
{
return options.layerAlpha;
}

View File

@@ -43,15 +43,17 @@ namespace fmri
/** /**
* Load rendering-specific options from the given options object. * Load rendering-specific options from the given options object.
* *
* @param options * @param programOptions
*/ */
void loadOptions(const Options& options); void loadOptions(const Options& programOptions);
/** /**
* @return Whether the network should only render activated nodes, rather than all of them. * @return Whether the network should only render activated nodes, rather than all of them.
*/ */
bool renderActivatedOnly() const; bool renderActivatedOnly() const;
bool renderInteractionPaths() const; bool renderInteractionPaths() const;
const Color& pathColor() const; const Color& pathColor() const;
float interactionAlpha() const;
float layerAlpha() const;
static RenderingState& instance(); static RenderingState& instance();
@@ -63,6 +65,8 @@ namespace fmri
bool renderInteractions = true; bool renderInteractions = true;
bool activatedOnly = false; bool activatedOnly = false;
bool renderInteractionPaths = false; bool renderInteractionPaths = false;
float layerAlpha;
float interactionAlpha;
Color pathColor; Color pathColor;
} options; } options;
std::array<float, 3> pos; std::array<float, 3> pos;

View File

@@ -59,8 +59,8 @@ int main(int argc, char *argv[])
// Prepare data for simulations // Prepare data for simulations
Options options = Options::parse(argc, argv); Options options = Options::parse(argc, argv);
loadSimulationData(options);
RenderingState::instance().loadOptions(options); RenderingState::instance().loadOptions(options);
loadSimulationData(options);
// Register callbacks // Register callbacks
glutReshapeFunc(changeWindowSize); glutReshapeFunc(changeWindowSize);

View File

@@ -31,7 +31,6 @@ auto file_filter_for_extension(std::string_view extension)
return filter; return filter;
} }
char * color_string(Gtk::ColorButton &button) char * color_string(Gtk::ColorButton &button)
{ {
char* buffer = new char[2 * 4 + 2]; // 2 per channel, plus #, plus null byte char* buffer = new char[2 * 4 + 2]; // 2 per channel, plus #, plus null byte
@@ -62,6 +61,15 @@ char* wrap_string(std::string_view str) {
return wrapper; return wrapper;
} }
void float_parameter(std::vector<char *> &argv, std::string_view flag, double value)
{
char buffer[100];
argv.push_back(wrap_string(flag));
std::sprintf(buffer, "%f", value);
argv.push_back(wrap_string(buffer));
}
class Launcher : public Gtk::Window { class Launcher : public Gtk::Window {
public: public:
Launcher(); Launcher();
@@ -78,6 +86,8 @@ private:
Gtk::FileChooserButton meansChooser; Gtk::FileChooserButton meansChooser;
Gtk::FileChooserButton inputChooser; Gtk::FileChooserButton inputChooser;
Gtk::ColorButton pathColor; Gtk::ColorButton pathColor;
Gtk::Scale layerTransparancy;
Gtk::Scale interactionTransparancy;
Gtk::Button startButton; Gtk::Button startButton;
void start(); void start();
@@ -99,6 +109,8 @@ Launcher::Launcher()
meansChooser("Select means file"), meansChooser("Select means file"),
inputChooser("Select input directory", Gtk::FileChooserAction::FILE_CHOOSER_ACTION_SELECT_FOLDER), inputChooser("Select input directory", Gtk::FileChooserAction::FILE_CHOOSER_ACTION_SELECT_FOLDER),
pathColor(Gdk::RGBA("rgba(255, 255, 255, 0.1)")), pathColor(Gdk::RGBA("rgba(255, 255, 255, 0.1)")),
layerTransparancy(Gtk::Adjustment::create(1, 0, 1, 0.0, 1.f / 256)),
interactionTransparancy(Gtk::Adjustment::create(1, 0, 1, 0.0, 1.f / 256)),
startButton("Start FMRI") startButton("Start FMRI")
{ {
set_default_size(400, -1); set_default_size(400, -1);
@@ -126,6 +138,8 @@ Launcher::Launcher()
addRowWithLabel("Input directory", inputChooser); addRowWithLabel("Input directory", inputChooser);
addRowWithLabel("Means (optional)", meansChooser); addRowWithLabel("Means (optional)", meansChooser);
addRowWithLabel("Path color", pathColor); addRowWithLabel("Path color", pathColor);
addRowWithLabel("Layer transparancy", layerTransparancy);
addRowWithLabel("Interaction transparancy", interactionTransparancy);
startButton.signal_clicked().connect(sigc::mem_fun(*this, &Launcher::start)); startButton.signal_clicked().connect(sigc::mem_fun(*this, &Launcher::start));
grid.attach_next_to(startButton, Gtk::PositionType::POS_BOTTOM, 2, 1); grid.attach_next_to(startButton, Gtk::PositionType::POS_BOTTOM, 2, 1);
@@ -162,6 +176,9 @@ void Launcher::start()
color_string(pathColor), color_string(pathColor),
}; };
float_parameter(argv, "--layer-opacity", layerTransparancy.get_adjustment()->get_value());
float_parameter(argv, "--interaction-opacity", interactionTransparancy.get_adjustment()->get_value());
if (labelChooser.get_file()) { if (labelChooser.get_file()) {
argv.push_back(wrap_string("-l")); argv.push_back(wrap_string("-l"));
argv.push_back(wrap_string(labelChooser.get_file()->get_path())); argv.push_back(wrap_string(labelChooser.get_file()->get_path()));
@@ -178,6 +195,11 @@ void Launcher::start()
argv.push_back(nullptr); argv.push_back(nullptr);
execv(executable.c_str(), argv.data()); execv(executable.c_str(), argv.data());
// Discard all allocated memory.
std::for_each(argv.begin(), argv.end(), std::default_delete<char>());
Gtk::MessageDialog dialog(*this, "Failed to start for unknown reasons.");
dialog.run();
} }
bool Launcher::hasFile(const Gtk::FileChooserButton& fileChooser, const std::string& error) bool Launcher::hasFile(const Gtk::FileChooserButton& fileChooser, const std::string& error)