From c0032aa688d60b871865b4dfa126d0afb43a42ba Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Thu, 29 Mar 2018 15:31:38 +0200 Subject: [PATCH] Allow hiding non-activated nodes. Refs #2. --- src/fmri/FlatLayerVisualisation.cpp | 47 +++++++++++++++++------------ src/fmri/FlatLayerVisualisation.hpp | 10 +++--- src/fmri/RenderingState.cpp | 12 +++++++- src/fmri/RenderingState.hpp | 5 +++ 4 files changed, 48 insertions(+), 26 deletions(-) diff --git a/src/fmri/FlatLayerVisualisation.cpp b/src/fmri/FlatLayerVisualisation.cpp index 24f108e..1169dbd 100644 --- a/src/fmri/FlatLayerVisualisation.cpp +++ b/src/fmri/FlatLayerVisualisation.cpp @@ -3,13 +3,13 @@ #include "FlatLayerVisualisation.hpp" #include "Range.hpp" +#include "RenderingState.hpp" -using namespace std; using namespace fmri; static inline void computeColor(float intensity, float limit, float *destination) { - const float saturation = min(-log(abs(intensity) / limit) / 10.0f, 1.0f); + const float saturation = std::min(-std::log(std::abs(intensity) / limit) / 10.0f, 1.0f); if (intensity > 0) { destination[0] = saturation; destination[1] = saturation; @@ -24,27 +24,26 @@ static inline void computeColor(float intensity, float limit, float *destination FlatLayerVisualisation::FlatLayerVisualisation(const LayerData &layer, Ordering ordering) : LayerVisualisation(layer.numEntries()), ordering(ordering), - faceCount(layer.numEntries() * NODE_FACES.size() / 3), - vertexBuffer(new float[faceCount * 3]), - colorBuffer(new float[faceCount * 3]), - indexBuffer(new int[faceCount * 3]) + vertexBuffer(layer.numEntries() * NODE_FACES.size()), + colorBuffer(layer.numEntries() * NODE_FACES.size()), + indexBuffer(layer.numEntries() * NODE_FACES.size()) { auto &shape = layer.shape(); - CHECK_EQ(shape.size(), 2) << "layer should be flat!" << endl; - CHECK_EQ(shape[0], 1) << "Only single images supported." << endl; + CHECK_EQ(shape.size(), 2) << "layer should be flat!\n"; + CHECK_EQ(shape[0], 1) << "Only single images supported.\n"; - initializeNodePositions(); + initializeNodePositions(layer.numEntries()); const auto limit = (int) layer.numEntries(); auto data = layer.data(); const auto - [minElem, maxElem] = minmax_element(data, data + limit); + [minElem, maxElem] = std::minmax_element(data, data + limit); - auto scalingMax = max(abs(*minElem), abs(*maxElem)); + auto scalingMax = std::max(abs(*minElem), abs(*maxElem)); int v = 0; for (int i : Range(limit)) { - setVertexPositions(i, vertexBuffer.get() + NODE_FACES.size() * i); + setVertexPositions(i, vertexBuffer.data() + NODE_FACES.size() * i); const auto vertexBase = static_cast(i * NODE_FACES.size() / 3); // Define the colors for the vertices @@ -57,7 +56,13 @@ FlatLayerVisualisation::FlatLayerVisualisation(const LayerData &layer, Ordering indexBuffer[v++] = vertexBase + faceNode; } } - assert(v == (int) faceCount * 3); + + // Compute which nodes are active, add those to the active indices + for (auto i : Range(limit)) { + if (abs(data[i]) > EPSILON) { + std::copy_n(&indexBuffer[NODE_FACES.size() * i], NODE_FACES.size(), std::back_inserter(activeIndexBuffer)); + } + } } void FlatLayerVisualisation::render() @@ -65,15 +70,17 @@ void FlatLayerVisualisation::render() glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vertexBuffer.get()); - glColorPointer(3, GL_FLOAT, 0, colorBuffer.get()); - glDrawElements(GL_TRIANGLES, faceCount * 3, GL_UNSIGNED_INT, indexBuffer.get()); + const auto& indices = RenderingState::instance().renderActivatedOnly() ? activeIndexBuffer : indexBuffer; + + glVertexPointer(3, GL_FLOAT, 0, vertexBuffer.data()); + glColorPointer(3, GL_FLOAT, 0, colorBuffer.data()); + glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, indices.data()); glDisableClientState(GL_COLOR_ARRAY); // Now draw wireframe glColor4f(0, 0, 0, 1); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - glDrawElements(GL_TRIANGLES, faceCount * 3, GL_UNSIGNED_INT, indexBuffer.get()); + glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, indices.data()); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); @@ -87,15 +94,15 @@ void FlatLayerVisualisation::setVertexPositions(const int vertexNo, float *desti } } -void FlatLayerVisualisation::initializeNodePositions() +void FlatLayerVisualisation::initializeNodePositions(std::size_t entries) { switch (ordering) { case Ordering::LINE: - initNodePositions(faceCount / 4, 2); + initNodePositions(entries, 2); break; case Ordering::SQUARE: - initNodePositions(faceCount / 4, 2); + initNodePositions(entries, 2); break; } } diff --git a/src/fmri/FlatLayerVisualisation.hpp b/src/fmri/FlatLayerVisualisation.hpp index 0a06ee7..7ebd0cf 100644 --- a/src/fmri/FlatLayerVisualisation.hpp +++ b/src/fmri/FlatLayerVisualisation.hpp @@ -16,10 +16,10 @@ namespace fmri private: Ordering ordering; - std::size_t faceCount; - std::unique_ptr vertexBuffer; - std::unique_ptr colorBuffer; - std::unique_ptr indexBuffer; + std::vector vertexBuffer; + std::vector colorBuffer; + std::vector indexBuffer; + std::vector activeIndexBuffer; static constexpr const std::array NODE_SHAPE = { -0.5f, 0, 0.5f, @@ -37,6 +37,6 @@ namespace fmri void setVertexPositions(int vertexNo, float *destination); // Various functions defining the way the nodes will be aligned. - void initializeNodePositions(); + void initializeNodePositions(std::size_t entries); }; } diff --git a/src/fmri/RenderingState.cpp b/src/fmri/RenderingState.cpp index 0d0cd99..02c924f 100644 --- a/src/fmri/RenderingState.cpp +++ b/src/fmri/RenderingState.cpp @@ -91,7 +91,11 @@ void RenderingState::handleKey(unsigned char x) exit(0); case 'h': - RenderingState::instance().reset(); + reset(); + break; + + case 'o': + toggle(options.activatedOnly); break; default: @@ -249,6 +253,7 @@ void RenderingState::renderOverlayText() const "F2: toggle debug info\n" "l: toggle layers visible\n" "i: toggle interactions visible\n" + "o: toggle activated nodes only\n" "q: quit\n"; } @@ -302,3 +307,8 @@ void RenderingState::handleSpecialKey(int key) LOG(INFO) << "Received keystroke " << key; } } + +bool RenderingState::renderActivatedOnly() const +{ + return options.activatedOnly; +} diff --git a/src/fmri/RenderingState.hpp b/src/fmri/RenderingState.hpp index bc25ef0..77033e1 100644 --- a/src/fmri/RenderingState.hpp +++ b/src/fmri/RenderingState.hpp @@ -39,6 +39,10 @@ namespace fmri void render(float time) const; void loadSimulationData(const std::map &info, std::vector> &&data); + /** + * @return Whether the network should only render activated nodes, rather than all of them. + */ + bool renderActivatedOnly() const; static RenderingState& instance(); @@ -48,6 +52,7 @@ namespace fmri bool showHelp = true; bool renderLayers = true; bool renderInteractions = true; + bool activatedOnly = false; } options; std::array pos; std::array angle;