Support layer and interaction transparancy. Refs #1
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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_;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user