Program Listing for File EnvironmentGraphVis.cpp

Return to documentation for file (src/flamegpu/visualiser/EnvironmentGraphVis.cpp)

#include "flamegpu/visualiser/EnvironmentGraphVis.h"


#include "flamegpu/simulation/detail/CUDAEnvironmentDirectedGraphBuffers.cuh"
#include "flamegpu/visualiser/LineVis.h"
#include "flamegpu/visualiser/config/LineConfig.h"

namespace flamegpu {
namespace visualiser {

EnvironmentGraphVisData::EnvironmentGraphVisData(std::shared_ptr <EnvironmentDirectedGraphData> _graphData, std::shared_ptr<LineConfig>_lines)
    : color(Stock::Colors::WHITE)
    , graphData(std::move(_graphData))
    , lines(std::move(_lines)) {
    const auto &x_it = graphData->vertexProperties.find("x");
    if (x_it != graphData->vertexProperties.end() &&
        x_it->second.type == std::type_index(typeid(float)) &&
        x_it->second.elements == 1) {
        x_varName = "x";
    }
    const auto &y_it = graphData->vertexProperties.find("y");
    if (y_it != graphData->vertexProperties.end() &&
        y_it->second.type == std::type_index(typeid(float)) &&
        y_it->second.elements == 1) {
        y_varName = "y";
    }
    const auto &z_it = graphData->vertexProperties.find("z");
    if (z_it != graphData->vertexProperties.end() &&
        z_it->second.type == std::type_index(typeid(float)) &&
        z_it->second.elements == 1) {
        z_varName = "z";
    }
}
void EnvironmentGraphVisData::constructGraph(const std::shared_ptr<detail::CUDAEnvironmentDirectedGraphBuffers> &graph) {
    // Can't construct prior to initialisation
    if (!graph->getVertexCount() && !graph->getEdgeCount())
        return;
    // Retrieve buffer data
    const float *x = nullptr;
    const float *y = nullptr;
    const float *z = nullptr;
    int x_stride = 1;
    int y_stride = 1;
    int z_stride = 1;
    if (!x_varName.empty() && !y_varName.empty()) {
        size_type ONE = 1;
        x = graph->getVertexPropertyBuffer<float>(x_varName, ONE, nullptr);
        y = graph->getVertexPropertyBuffer<float>(y_varName, ONE, nullptr);
        if (!z_varName.empty())
            z = graph->getVertexPropertyBuffer<float>(z_varName, ONE, nullptr);
    } else if (!xy_varName.empty()) {
        size_type TWO = 1;
        const float* xy = graph->getVertexPropertyBuffer<float>(xy_varName, TWO, nullptr);
        x = xy;
        y = x+1;
        x_stride = 2;
        y_stride = 2;
    } else if (!xyz_varName.empty()) {
        size_type THREE = 1;
        const float* xyz = graph->getVertexPropertyBuffer<float>(xyz_varName, THREE, nullptr);
        x = xyz;
        y = x + 1;
        z = y + 1;
        x_stride = 3;
        y_stride = 3;
        z_stride = 3;
    } else {
        throw exception::InvalidOperation("Unable to construct graph visualisation, appropriate vertex variables not set, in EnvironmentGraphVisData::constructGraph()");
    }
    // Update line sketch
    auto ln = LineVis(lines, color.r, color.g, color.b, color.a);
    ln.clear();
    // Iterate edges
    size_type TWO = 2;
    const id_t *edges = graph->getEdgePropertyBuffer<id_t>(GRAPH_SOURCE_DEST_VARIABLE_NAME, TWO, nullptr);
    for (unsigned int i = 0; i < graph->getEdgeCount(); ++i) {
        // Sketch destination vertex
        const size_type dest_i = graph->getVertexIndex(edges[i * 2]);
        if (z) {
            ln.addVertex(x[dest_i * x_stride], y[dest_i * y_stride], z[dest_i * z_stride]);
        } else {
            ln.addVertex(x[dest_i * x_stride], y[dest_i * y_stride]);
        }
        // Sketch source vertex
        const size_type src_i = graph->getVertexIndex(edges[(i * 2) + 1]);
        if (z) {
            ln.addVertex(x[src_i * x_stride], y[src_i * y_stride], z[src_i * z_stride]);
        } else {
            ln.addVertex(x[src_i * x_stride], y[src_i * y_stride]);
        }
    }
}

EnvironmentGraphVis::EnvironmentGraphVis(std::shared_ptr<EnvironmentGraphVisData> _data)
    : data(std::move(_data)) { }

void EnvironmentGraphVis::setXVertexProperty(const std::string &var_name) {
    auto it = data->graphData->vertexProperties.find(var_name);
    if (it == data->graphData->vertexProperties.end()) {
        THROW exception::InvalidEnvProperty("Property '%s' was not found within graph '%s', "
            "in EnvironmentGraphVis::setXProperty()\n",
            var_name.c_str(), data->graphData->name.c_str());
    } else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
        THROW exception::InvalidEnvProperty("Visualisation position x property must be type float[1], graph '%s' property '%s' is type %s[%u], "
            "in EnvironmentGraphVis::setXProperty()\n",
            data->graphData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
    }
    data->xy_varName.clear();
    data->xyz_varName.clear();
    data->x_varName = var_name;
}
void EnvironmentGraphVis::setYVertexProperty(const std::string &var_name) {
    auto it = data->graphData->vertexProperties.find(var_name);
    if (it == data->graphData->vertexProperties.end()) {
        THROW exception::InvalidEnvProperty("Property '%s' was not found within graph '%s', "
            "in EnvironmentGraphVis::setYProperty()\n",
            var_name.c_str(), data->graphData->name.c_str());
    } else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
        THROW exception::InvalidEnvProperty("Visualisation position y property must be type float[1], graph '%s' property '%s' is type %s[%u], "
            "in EnvironmentGraphVis::setYProperty()\n",
            data->graphData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
    }
    data->xy_varName.clear();
    data->xyz_varName.clear();
    data->y_varName = var_name;
}
void EnvironmentGraphVis::setZVertexProperty(const std::string &var_name) {
    auto it = data->graphData->vertexProperties.find(var_name);
    if (it == data->graphData->vertexProperties.end()) {
        THROW exception::InvalidEnvProperty("Property '%s' was not found within graph '%s', "
            "in EnvironmentGraphVis::setZProperty()\n",
            var_name.c_str(), data->graphData->name.c_str());
    } else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 1) {
        THROW exception::InvalidEnvProperty("Visualisation position z property must be type float[1], graph '%s' property '%s' is type %s[%u], "
            "in EnvironmentGraphVis::setZProperty()\n",
            data->graphData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
    }
    data->xy_varName.clear();
    data->xyz_varName.clear();
    data->z_varName = var_name;
}
void EnvironmentGraphVis::setXYVertexProperty(const std::string& var_name) {
    auto it = data->graphData->vertexProperties.find(var_name);
    if (it == data->graphData->vertexProperties.end()) {
        THROW exception::InvalidEnvProperty("Property '%s' was not found within graph '%s', "
            "in EnvironmentGraphVis::setXYProperty()\n",
            var_name.c_str(), data->graphData->name.c_str());
    } else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 2) {
        THROW exception::InvalidEnvProperty("Visualisation position x property must be type float[2], graph '%s' property '%s' is type %s[%u], "
            "in EnvironmentGraphVis::setXYProperty()\n",
            data->graphData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
    }
    data->x_varName.clear();
    data->y_varName.clear();
    data->z_varName.clear();
    data->xyz_varName.clear();
    data->xy_varName = var_name;
}
void EnvironmentGraphVis::setXYZVertexProperty(const std::string& var_name) {
    auto it = data->graphData->vertexProperties.find(var_name);
    if (it == data->graphData->vertexProperties.end()) {
        THROW exception::InvalidEnvProperty("Property '%s' was not found within graph '%s', "
            "in EnvironmentGraphVis::setXYZProperty()\n",
            var_name.c_str(), data->graphData->name.c_str());
    } else if (it->second.type != std::type_index(typeid(float)) || it->second.elements != 3) {
        THROW exception::InvalidEnvProperty("Visualisation position x property must be type float[3], graph '%s' property '%s' is type %s[%u], "
            "in EnvironmentGraphVis::setXYZProperty()\n",
            data->graphData->name.c_str(), var_name.c_str(), it->second.type.name(), it->second.elements);
    }
    data->x_varName.clear();
    data->y_varName.clear();
    data->y_varName.clear();
    data->xy_varName.clear();
    data->xyz_varName = var_name;
}
void EnvironmentGraphVis::setColor(const Color& color) {
    data->color = color;
}
}  // namespace visualiser
}  // namespace flamegpu