Commit 51f98fac authored by tonynsyde's avatar tonynsyde

Moving VTKWriter for dist_graph

parent 59f5019f
/*
* VTKWriter_graph.hpp
*
* Created on: May 5, 2015
* Author: Pietro Incardona
*/
#ifndef VTKWRITER_DIST_GRAPH_HPP_
#define VTKWRITER_DIST_GRAPH_HPP_
#include "VCluster.hpp"
/*! Property data store for scalar and vector
*
*/
template<bool is_array>
struct vtk_dist_vertex_node_array_scalar_selector
{
/*! /brief Print the geometric informations in case it is not an array
*
* \tparam T Type of the vertex
* \tparam ele_v Attribute element to check
* \tparam G Graph of reference
* \tparam s_type Vertex spatial type information
*
* \param vo Vertex object container
* \param x Array to store geometric informations
* \param z_set Value set to true id z axis is in use
*/
template<typename T, typename ele_v, typename G, typename s_type>
static inline void move(typename G::V_container &vo, s_type (&x)[3], bool &z_set)
{
if (G::V_type::attributes::name[T::value] == "x")
{
x[0] = convert<typename boost::remove_reference<decltype(vo.template get<T::value>())>::type>::template to<s_type>(vo.template get<T::value>());
}
else if (G::V_type::attributes::name[T::value] == "y")
{
x[1] = convert<typename boost::remove_reference<decltype(vo.template get<T::value>())>::type>::template to<s_type>(vo.template get<T::value>());
}
else if (G::V_type::attributes::name[T::value] == "z")
{
x[2] = convert<typename boost::remove_reference<decltype(vo.template get<T::value>())>::type>::template to<s_type>(vo.template get<T::value>());
z_set = true;
}
}
};
/*! Template specialization in the case of array type attribute
*
*/
template<>
struct vtk_dist_vertex_node_array_scalar_selector<true>
{
/*! \brief Store the geometric informations in case it is an array
*
* \tparam T Type of the vertex
* \tparam ele_v Attribute element to check
* \tparam G Graph of reference
* \tparam s_type Vertex spatial type information
*
* \param vo Vertex object container
* \param x Array to store geometric informations
* \param z_set Value set to true id z axis is in use
*/
template<typename T, typename ele_v, typename G, typename s_type>
static inline void move(typename G::V_container &vo, s_type (&x)[3], bool &z_set)
{
if (std::extent<ele_v>::value == 3)
z_set = true;
for (size_t i = 0; i < std::extent<ele_v>::value; i++)
x[i] = convert<typename boost::remove_reference<decltype(vo.template get<T::value>()[i])>::type>::template to<s_type>(vo.template get<T::value>()[i]);
}
};
/*! \brief this class is a functor for "for_each" algorithm
*
* This class is a functor for "for_each" algorithm. For each
* element of the boost::vector the operator() is called.
* Is mainly used to create a string containing all the vertex
* properties
*
* \tparam G graph type
* \tparam attr has the vertex attributes
*
*/
template<typename G, bool attr>
struct vtk_dist_vertex_node
{
// Vertex spatial type information
typedef typename G::V_type::s_type s_type;
bool z_set;
s_type (&x)[3];
// Vertex object container
typename G::V_container & vo;
// vertex node string
std::string & v_node;
/*! \brief Constructor
*
* Create a vertex properties list
*
* \param v_node std::string that is filled with the graph properties in the GraphML format
* \param n_obj object container to access its properties for example encapc<...>
*
*/
vtk_dist_vertex_node(std::string & v_node, typename G::V_container & n_obj, s_type (&x)[3]) :
x(x), vo(n_obj), v_node(v_node), z_set(false)
{
}
;
//! \brief Write collected information
void write()
{
v_node += std::to_string(x[0]) + " " + std::to_string(x[1]) + " " + std::to_string(x[2]) + "\n";
}
//! It call the functor for each member
template<typename T>
void operator()(T& t)
{
typedef typename boost::mpl::at<typename G::V_type::type, boost::mpl::int_<T::value>>::type ele_v;
// if the attribute name is x y or z, create a string with the value of the properties and store it
vtk_dist_vertex_node_array_scalar_selector<std::is_array<ele_v>::value>::template move<T, ele_v, G, s_type>(vo, x, z_set);
}
};
/*! \brief this class is a functor for "for_each" algorithm
*
* This class is a functor for "for_each" algorithm. For each
* element of the boost::vector the operator() is called.
* Is mainly used to create a string containing all the vertex
* properties
*
* Specialization when we do not have vertex attributes
*
* \tparam G graph type
*
*/
template<typename G>
struct vtk_dist_vertex_node<G, false>
{
// Vertex object container
typename G::V_container & vo;
// vertex node string
std::string & v_node;
/*! \brief Constructor
*
* Create a vertex properties list
*
* \param v_node std::string that is filled with the graph properties in the GraphML format
* \param n_obj object container to access its properties for example encapc<...>
*
*/
vtk_dist_vertex_node(std::string & v_node, typename G::V_container & n_obj) :
vo(n_obj), v_node(v_node)
{
}
;
//! It call the functor for each member
template<typename T>
void operator()(T& t)
{
v_node += "0 0 0\n";
}
};
/*! \brief this class is a functor for "for_each" algorithm
*
* This class is a functor for "for_each" algorithm. For each
* element of the boost::vector the operator() is called.
* Is mainly used to create a string containing all the edge
* properties
*
*/
template<typename G>
struct vtk_dist_edge_node
{
// Vertex object container
typename G::E_container & vo;
// edge node string
std::string & e_node;
/*! \brief Constructor
*
* Create an edge node
*
* \param e_node std::string that is filled with the graph properties in the GraphML format
* \param n_obj object container to access the object properties for example encapc<...>
* \param n_prop number of properties
*
*/
vtk_dist_edge_node(std::string & e_node, typename G::E_container & n_obj) :
vo(n_obj), e_node(e_node)
{
}
;
/*! \brief Create a new node
*
* \param vc node number
*
*/
void new_node(size_t v_c, size_t s, size_t d)
{
// start a new node
e_node += "2 " + std::to_string(s) + " " + std::to_string(d) + "\n";
}
};
/*! \brief Property writer for scalar and vector
*
*/
template<bool is_array>
struct dist_prop_output_array_scalar_selector_vertex
{
/*! \brief Writer in case the property is not an array
*
* \tparam ele_v Property element
* \tparam Graph Graph of reference
* \tparam i Property id
*
* \param v_out Buffer to write into
* \param g Graph
* \param p Property id
*/
template<typename ele_v, typename Graph, unsigned int i>
static inline void write(std::string &v_out, const Graph &g, size_t p)
{
v_out += std::to_string(g.vertex(p).template get<i>()) + "\n";
}
};
/*! \brief Property writer for vector
*
*/
template<>
struct dist_prop_output_array_scalar_selector_vertex<true>
{
/*! \brief Writer in case the property is an array
*
* \tparam ele_v Property element
* \tparam Graph Graph of reference
* \tparam i Property id
*
* \param v_out Buffer to write into
* \param g Graph
* \param p Property id
*/
template<typename ele_v, typename Graph, unsigned int i>
static inline void write(std::string &v_out, const Graph &g, size_t p)
{
for (size_t j = 0; j < 2; j++)
{
v_out += std::to_string(g.vertex(p).template get<i>()[j]) + " ";
}
if (std::extent<ele_v>::value == 2)
v_out += "0";
else
v_out += std::to_string(g.vertex(p).template get<i>()[2]);
v_out += "\n";
}
};
/*! \brief Property writer for scalar and vector
*
*/
template<bool is_array>
struct dist_prop_output_array_scalar_selector_edge
{
/*! \brief Writer in case the property is not an array
*
* \tparam ele_v Property element
* \tparam Graph Graph of reference
* \tparam i Property id
*
* \param v_out Buffer to write into
* \param g Graph
* \param p Property id
*/
template<typename ele_v, typename Graph, unsigned int i>
static inline void write(std::string &v_out, const Graph &g, const typename Graph::E_container &edge)
{
v_out += std::to_string(edge.template get<i>()) + "\n";
}
};
/*! \brief Property writer for vector
*
*/
template<>
struct dist_prop_output_array_scalar_selector_edge<true>
{
/*! \brief Writer in case the property is an array
*
* \tparam ele_v Property element
* \tparam Graph Graph of reference
* \tparam i Property id
*
* \param v_out Buffer to write into
* \param g Graph
* \param p Property id
*/
template<typename ele_v, typename Graph, unsigned int i>
static inline void write(std::string &v_out, const Graph &g, const typename Graph::E_container &edge)
{
for (size_t j = 0; j < 2; j++)
{
v_out += std::to_string(edge.template get<i>()[j]) + " ";
}
if (std::extent<ele_v>::value == 2)
v_out += "0";
else
v_out += std::to_string(edge.template get<i>()[2]);
v_out += "\n";
}
};
/*! \brief Property writer for scalar and vector, it fill the vertex data (needed for edge representation in vtk)
*
*/
template<bool is_array>
struct dist_prop_output_array_scalar_selector_edge_fill_vertex
{
/*! \brief Writer in case the property is not an array
*
* \param v_out Buffer to write into
*/
static inline void write(std::string &v_out)
{
v_out += "0\n";
}
};
/*! \brief Property writer for vector
*
*/
template<>
struct dist_prop_output_array_scalar_selector_edge_fill_vertex<true>
{
/*! \brief Writer in case the property is an array
*
* \param v_out Buffer to write into
*/
static inline void write(std::string &v_out)
{
v_out += "0 0 0\n";
}
};
/*! \brief This class specialize functions in the case the type T
* has or not defined attributes
*
* In C++ partial specialization of a function is not allowed so we have to
* encapsulate this function in a class
*
* \tparam has_attributes parameter that specialize the function in case the vertex
* define or not attributes name
*
* \tparam Graph type of graph we are processing
* \tparam i the property we are going to write
*
*/
template<bool has_attributes, typename Graph, unsigned int i>
class dist_prop_output
{
public:
/*! \brief For each vertex set the value
*
* \tparam i vertex property to print
*
*/
static std::string get_point_data(const Graph & g)
{
//! vertex node output string
std::string v_out;
//! Get a vertex iterator
auto it = g.getVertexIterator();
// if there is the next element
while (it.isNext())
{
typedef typename boost::mpl::at<typename Graph::V_type::type, boost::mpl::int_<i>>::type ele_v;
dist_prop_output_array_scalar_selector_vertex<std::is_array<ele_v>::value>::template write<ele_v, Graph, i>(v_out, g, it.get());
// increment the iterator and counter
++it;
}
return v_out;
}
/*! \brief For each edge set the value, set 1 on vertices, needed by vtk file format
*
* \tparam i edge property to print
*
*/
static std::string get_cell_data(const Graph & g)
{
//! vertex node output string
std::string e_out;
//! Get a vertex iterator
auto it_v = g.getVertexIterator();
// if there is the next element
while (it_v.isNext())
{
// Print the property
typedef typename boost::mpl::at<typename Graph::E_type::type, boost::mpl::int_<i>>::type ele_v;
dist_prop_output_array_scalar_selector_edge_fill_vertex<std::is_array<ele_v>::value>::write(e_out);
// increment the iterator and counter
++it_v;
}
//! Get an edge iterator
auto it_e = g.getEdgeIterator();
// if there is the next element
while (it_e.isNext())
{
typedef typename boost::mpl::at<typename Graph::E_type::type, boost::mpl::int_<i>>::type ele_v;
dist_prop_output_array_scalar_selector_edge<std::is_array<ele_v>::value>::template write<ele_v, Graph, i>(e_out, g, g.edge(it_e.get()));
// increment the iterator and counter
++it_e;
}
return e_out;
}
/*! \brief Given a Graph return the point data header for a typename T
*
* \tparam T type to write
* \param n_node number of the node
*
*/
static std::string get_point_property_header(size_t prop)
{
//! vertex node output string
std::string v_out;
// Type of the property
std::string type;
typedef typename boost::mpl::at<typename Graph::V_type::type, boost::mpl::int_<i>>::type T;
// Check if T is a supported format
// for now we support only scalar of native type
if (std::is_array<T>::value == true && std::is_array<typename std::remove_extent<T>::type>::value == false)
{
//Get type of the property
type = getType<typename std::remove_all_extents<T>::type>();
// if the type is not supported return
if (type.size() == 0)
return v_out;
// Create point data properties
v_out += "VECTORS " + get_attributes_vertex() + " " + type + "\n";
}
else
{
type = getType<T>();
// if the type is not supported return
if (type.size() == 0)
return v_out;
// Create point data properties
v_out += "SCALARS " + get_attributes_vertex() + " " + type + "\n";
// Default lookup table
v_out += "LOOKUP_TABLE default\n";
}
// return the vertex list
return v_out;
}
/*! \brief Given a Graph return the cell data header for a typename T
*
* \tparam T type to write
* \param n_node number of the node
*
*/
static std::string get_cell_property_header(size_t prop)
{
//! edge node output string
std::string e_out;
// Type of the property
std::string type;
typedef typename boost::mpl::at<typename Graph::E_type::type, boost::mpl::int_<i>>::type T;
// Check if T is a supported format
// for now we support only scalar of native type
if (std::is_array<T>::value == true && std::is_array<typename std::remove_extent<T>::type>::value == false)
{
//Get type of the property
type = getType<typename std::remove_all_extents<T>::type>();
// if the type is not supported return
if (type.size() == 0)
return e_out;
// Create point data properties
e_out += "VECTORS " + get_attributes_edge() + " " + type + "\n";
}
else
{
type = getType<T>();
// if the type is not supported return
if (type.size() == 0)
return e_out;
// Create point data properties
e_out += "SCALARS " + get_attributes_edge() + " " + type + "\n";
// Default lookup table
e_out += "LOOKUP_TABLE default\n";
}
// return the vertex list
return e_out;
}
/*! \brief Get the attributes name for vertex
*
*/
static std::string get_attributes_vertex()
{
return Graph::V_type::attributes::name[i];
}
/*! \brief Get the attributes name for edge
*
*/
static std::string get_attributes_edge()
{
return Graph::E_type::attributes::name[i];
}
};
/*! \brief This class specialize functions in the case the type T
* has not defined attributes
*
* In C++ partial specialization of a function is not allowed so we have to
* encapsulate this function in a class
*
* \tparam has_attributes parameter that specialize the function in case the vertex
* define or not attributes name
*
* \tparam i id of the property we are going to write
*
*/
template<typename Graph, unsigned int i>
class dist_prop_output<false, Graph, i>
{
/*! \brief For each vertex set the value
*
* \tparam i vertex property to print
*
*/
static std::string get_point_data(Graph & g)
{
//! vertex node output string
std::string v_out;
//! Get a vertex iterator
auto it = g.getVertexIterator();
// if there is the next element
while (it.isNext())
{
// Print the property
v_out += std::to_string(g.vertex(it.get()).template get<i>()) + "\n";
// increment the iterator and counter
++it;
}
return v_out;
}
/*! \brief For each edge set the value
*
* \tparam i edge property to print
*
*/
static std::string get_cell_data(const Graph & g)
{
//! vertex node output string
std::string e_out;
//! Get a vertex iterator
auto it_v = g.getVertexIterator();
// if there is the next element
while (it_v.isNext())
{
// Print the property
e_out += std::to_string(0) + "\n";