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 + interactions.size());
}
patchTransparancy(colorBuf.begin(), colorBuf.end());
}
void ActivityAnimation::draw(float timeScale)

View File

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

View File

@@ -1,6 +1,8 @@
#pragma once
#include "utils.hpp"
namespace fmri
{
class Animation
@@ -10,5 +12,21 @@ namespace fmri
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(colorPos == colorBuffer.end());
patchTransparancy(colorBuffer.begin(), colorBuffer.end());
}
void FlatLayerVisualisation::render()

View File

@@ -1,6 +1,7 @@
#include "LayerVisualisation.hpp"
#include "Range.hpp"
#include "utils.hpp"
#include "RenderingState.hpp"
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<>
void fmri::LayerVisualisation::initNodePositions<fmri::LayerVisualisation::Ordering::SQUARE>(size_t n, float spacing)
{

View File

@@ -1,6 +1,7 @@
#pragma once
#include <vector>
#include "utils.hpp"
namespace fmri
{
@@ -19,10 +20,25 @@ namespace fmri
virtual void render() = 0;
virtual const std::vector<float>& nodePositions() const;
private:
static float getAlpha();
protected:
std::vector<float> nodePositions_;
template<Ordering Order>
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")
("means,m", value<std::string>(&options.meansPath), "means file")
("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");
options_description composed = desc;
@@ -92,12 +94,12 @@ Options Options::parse(const int argc, char *const argv[])
// Sanity checks
check_file(options.modelPath);
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);
return options;
} catch (required_option& e) {
std::cerr << e.get_option_name() << std::endl;
if (e.get_option_name() == "--input") {
std::cerr << "No input files specified" << std::endl;
} else {
@@ -149,6 +151,8 @@ std::optional<PNGDumper> Options::imageDumper() const
}
Options::Options() noexcept :
layerTransparancy_(1),
interactionTransparancy_(1),
pathColor_({1, 1, 1, 0.1})
{
}
@@ -157,3 +161,13 @@ const Color &Options::pathColor() const
{
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;
std::optional<vector<string>> labels() const;
std::optional<fmri::PNGDumper> imageDumper() const;
float layerTransparancy() const;
float interactionTransparancy() const;
const vector<string>& inputs() const;
private:
float layerTransparancy_;
float interactionTransparancy_;
Color pathColor_;
string modelPath;
string weightsPath;

View File

@@ -341,9 +341,11 @@ bool RenderingState::renderInteractionPaths() const
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
@@ -369,3 +371,13 @@ RenderingState::RenderingState() noexcept
// Set initial point size
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.
*
* @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.
*/
bool renderActivatedOnly() const;
bool renderInteractionPaths() const;
const Color& pathColor() const;
float interactionAlpha() const;
float layerAlpha() const;
static RenderingState& instance();
@@ -63,6 +65,8 @@ namespace fmri
bool renderInteractions = true;
bool activatedOnly = false;
bool renderInteractionPaths = false;
float layerAlpha;
float interactionAlpha;
Color pathColor;
} options;
std::array<float, 3> pos;

View File

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

View File

@@ -31,7 +31,6 @@ auto file_filter_for_extension(std::string_view extension)
return filter;
}
char * color_string(Gtk::ColorButton &button)
{
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;
}
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 {
public:
Launcher();
@@ -78,6 +86,8 @@ private:
Gtk::FileChooserButton meansChooser;
Gtk::FileChooserButton inputChooser;
Gtk::ColorButton pathColor;
Gtk::Scale layerTransparancy;
Gtk::Scale interactionTransparancy;
Gtk::Button startButton;
void start();
@@ -99,6 +109,8 @@ Launcher::Launcher()
meansChooser("Select means file"),
inputChooser("Select input directory", Gtk::FileChooserAction::FILE_CHOOSER_ACTION_SELECT_FOLDER),
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")
{
set_default_size(400, -1);
@@ -126,6 +138,8 @@ Launcher::Launcher()
addRowWithLabel("Input directory", inputChooser);
addRowWithLabel("Means (optional)", meansChooser);
addRowWithLabel("Path color", pathColor);
addRowWithLabel("Layer transparancy", layerTransparancy);
addRowWithLabel("Interaction transparancy", interactionTransparancy);
startButton.signal_clicked().connect(sigc::mem_fun(*this, &Launcher::start));
grid.attach_next_to(startButton, Gtk::PositionType::POS_BOTTOM, 2, 1);
@@ -162,6 +176,9 @@ void Launcher::start()
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()) {
argv.push_back(wrap_string("-l"));
argv.push_back(wrap_string(labelChooser.get_file()->get_path()));
@@ -178,6 +195,11 @@ void Launcher::start()
argv.push_back(nullptr);
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)