Skip to content
Snippets Groups Projects
Commit e4e46139 authored by Astrid Beyer's avatar Astrid Beyer
Browse files

feat: new executable to create dot file from vtp

parent bc756d65
No related branches found
No related tags found
No related merge requests found
......@@ -2,22 +2,37 @@ cmake_minimum_required(VERSION 3.8)
# name of the project
project(projet-stage)
set(CMAKE_CXX_STANDARD 11)
# Search for library TTK/VTK
find_package(TTKVTK REQUIRED)
# Add src files
add_executable(projet-stage main.cpp operation_mesh.cpp vtkOFFReader.cxx)
target_link_libraries(projet-stage
PUBLIC
ttk::vtk::ttkAll
PRIVATE ${VTK_LIBRARIES}
)
# vtk_module_autoinit is needed
# Adding vtkPolyDataToGraph
add_library(vtkPolyDataToGraph STATIC vtkPolyDataToGraph.cxx)
target_link_libraries(vtkPolyDataToGraph
PUBLIC
ttk::vtk::ttkAll
PRIVATE ${VTK_LIBRARIES}
)
# vtp2dot executable
add_executable(vpt2dot vpt2dot.cxx vtkPolyDataToGraph.cxx)
target_link_libraries(vpt2dot
PUBLIC
vtkPolyDataToGraph ttk::vtk::ttkAll
PRIVATE ${VTK_LIBRARIES}
)
# vtk_module
vtk_module_autoinit(
TARGETS projet-stage
TARGETS projet-stage vpt2dot
MODULES ${VTK_LIBRARIES}
)
\ No newline at end of file
#include <vtkSmartPointer.h>
#include <vtkXMLPolyDataReader.h>
#include <vtkCommand.h>
#include <vtkGraphToPolyData.h>
#include "vtkPolyDataToGraph.h"
#include "vtkBoostGraphAdapter.h"
#include <boost/graph/graphviz.hpp>
#include <vtkCallbackCommand.h>
#include <vtkCommand.h>
#define VTK_CREATE(type, name) vtkSmartPointer<type> name = vtkSmartPointer<type>::New()
void FilterEventHandlerVTK(vtkObject *caller, long unsigned int eventId, void *clientData, void *callData)
{
vtkAlgorithm *filter = static_cast<vtkAlgorithm *>(caller);
switch (eventId)
{
case vtkCommand::ProgressEvent:
fprintf(stderr, "\r%s progress: %5.1f%%", filter->GetClassName(), 100.0 * filter->GetProgress()); // stderr is flushed directly
break;
case vtkCommand::EndEvent:
std::cerr << std::endl
<< std::flush;
break;
//// VTK does not throw errors (http://public.kitware.com/pipermail/vtkusers/2009-February/050805.html) use Error-Events: http://www.cmake.org/Wiki/VTK/Examples/Cxx/Utilities/ObserveError
case vtkCommand::ErrorEvent:
std::cerr << "Error: " << static_cast<char *>(callData) << std::endl
<< std::flush;
break;
case vtkCommand::WarningEvent:
std::cerr << "Warning: " << static_cast<char *>(callData) << std::endl
<< std::flush;
break;
}
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
std::cerr << "Usage: " << argv[0]
<< " input"
<< " output"
<< std::endl;
return EXIT_FAILURE;
}
if (!(strcasestr(argv[1], ".vtp")))
{
std::cerr << "The input should end with .vtp" << std::endl;
return -1;
}
if (!(strcasestr(argv[2], ".dot") || strcasestr(argv[2], ".gv")))
{
std::cerr << "The output should end with .dot or .gv" << std::endl;
return -1;
}
VTK_CREATE(vtkCallbackCommand, eventCallbackVTK);
eventCallbackVTK->SetCallback(FilterEventHandlerVTK);
VTK_CREATE(vtkXMLPolyDataReader, reader);
reader->SetFileName(argv[1]);
reader->AddObserver(vtkCommand::AnyEvent, eventCallbackVTK);
reader->Update();
// VTK_CREATE(vtkPolyDataToGraph, filter);
vtkSmartPointer<vtkPolyDataToGraph> filter;
filter->SetInputConnection(0, reader->GetOutputPort());
filter->AddObserver(vtkCommand::AnyEvent, eventCallbackVTK);
filter->Update();
vtkUndirectedGraph *graph = vtkUndirectedGraph::SafeDownCast(filter->GetOutput());
std::ofstream fout(argv[2]);
boost::write_graphviz(fout, graph);
return EXIT_SUCCESS;
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkBoostGraphAdapter.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
/*-------------------------------------------------------------------------
Copyright 2008 Sandia Corporation.
Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
#ifndef vtkBoostGraphAdapter_h
#define vtkBoostGraphAdapter_h
#include "vtkAbstractArray.h"
#include "vtkDataArray.h"
#include "vtkDataObject.h"
#include "vtkDirectedGraph.h"
#include "vtkDistributedGraphHelper.h"
#include "vtkDoubleArray.h"
#include "vtkFloatArray.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkIntArray.h"
#include "vtkMutableDirectedGraph.h"
#include "vtkMutableUndirectedGraph.h"
#include "vtkTree.h"
#include "vtkUndirectedGraph.h"
#include "vtkVariant.h"
#include <boost/version.hpp>
namespace boost
{
//===========================================================================
// VTK arrays as property maps
// These need to be defined before including other boost stuff
// Forward declarations are required here, so that we aren't forced
// to include boost/property_map.hpp.
template <typename>
struct property_traits;
struct read_write_property_map_tag;
#define vtkPropertyMapMacro(T, V) \
template <> \
struct property_traits<T *> \
{ \
typedef V value_type; \
typedef V reference; \
typedef vtkIdType key_type; \
typedef read_write_property_map_tag category; \
}; \
\
inline property_traits<T *>::reference get(T *const &arr, property_traits<T *>::key_type key) \
{ \
return arr->GetValue(key); \
} \
\
inline void put( \
T *arr, property_traits<T *>::key_type key, const property_traits<T *>::value_type &value) \
{ \
arr->InsertValue(key, value); \
}
vtkPropertyMapMacro(vtkIntArray, int);
vtkPropertyMapMacro(vtkIdTypeArray, vtkIdType);
vtkPropertyMapMacro(vtkDoubleArray, double);
vtkPropertyMapMacro(vtkFloatArray, float);
// vtkDataArray
template <>
struct property_traits<vtkDataArray *>
{
typedef double value_type;
typedef double reference;
typedef vtkIdType key_type;
typedef read_write_property_map_tag category;
};
inline double get(vtkDataArray *const &arr, vtkIdType key)
{
return arr->GetTuple1(key);
}
inline void put(vtkDataArray *arr, vtkIdType key, const double &value)
{
arr->SetTuple1(key, value);
}
// vtkAbstractArray as a property map of vtkVariants
template <>
struct property_traits<vtkAbstractArray *>
{
typedef vtkVariant value_type;
typedef vtkVariant reference;
typedef vtkIdType key_type;
typedef read_write_property_map_tag category;
};
inline vtkVariant get(vtkAbstractArray *const &arr, vtkIdType key)
{
return arr->GetVariantValue(key);
}
inline void put(vtkAbstractArray *arr, vtkIdType key, const vtkVariant &value)
{
arr->InsertVariantValue(key, value);
}
#if defined(_MSC_VER)
namespace detail
{
using ::boost::get;
using ::boost::put;
}
#endif
}
#include <utility> // STL Header
#include <boost/config.hpp>
#include <boost/version.hpp>
#if BOOST_VERSION > 107300 && BOOST_VERSION < 107600
#define BOOST_ALLOW_DEPRECATED_HEADERS
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#endif
#include <boost/graph/adjacency_iterator.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
#include <boost/iterator/iterator_facade.hpp>
// The functions and classes in this file allows the user to
// treat a vtkDirectedGraph or vtkUndirectedGraph object
// as a boost graph "as is".
namespace boost
{
class vtk_vertex_iterator
: public iterator_facade<vtk_vertex_iterator, vtkIdType, bidirectional_traversal_tag,
const vtkIdType &, vtkIdType>
{
public:
explicit vtk_vertex_iterator(vtkIdType i = 0)
: index(i)
{
}
private:
const vtkIdType &dereference() const { return index; }
bool equal(const vtk_vertex_iterator &other) const { return index == other.index; }
void increment() { index++; }
void decrement() { index--; }
vtkIdType index;
friend class iterator_core_access;
};
class vtk_edge_iterator
: public iterator_facade<vtk_edge_iterator, vtkEdgeType, forward_traversal_tag,
const vtkEdgeType &, vtkIdType>
{
public:
explicit vtk_edge_iterator(vtkGraph *g = nullptr, vtkIdType v = 0)
: directed(false), vertex(v), lastVertex(v), iter(nullptr), end(nullptr), graph(g)
{
if (graph)
{
lastVertex = graph->GetNumberOfVertices();
}
vtkIdType myRank = -1;
vtkDistributedGraphHelper *helper =
this->graph ? this->graph->GetDistributedGraphHelper() : nullptr;
if (helper)
{
myRank = this->graph->GetInformation()->Get(vtkDataObject::DATA_PIECE_NUMBER());
vertex = helper->MakeDistributedId(myRank, vertex);
lastVertex = helper->MakeDistributedId(myRank, lastVertex);
}
if (graph != nullptr)
{
directed = (vtkDirectedGraph::SafeDownCast(graph) != nullptr);
while (vertex < lastVertex && this->graph->GetOutDegree(vertex) == 0)
{
++vertex;
}
if (vertex < lastVertex)
{
// Get the outgoing edges of the first vertex that has outgoing
// edges
vtkIdType nedges;
graph->GetOutEdges(vertex, iter, nedges);
if (iter)
{
end = iter + nedges;
if (!directed)
{
while ( // Skip non-local edges
(helper && helper->GetEdgeOwner(iter->Id) != myRank)
// Skip entirely-local edges where Source > Target
|| (((helper && myRank == helper->GetVertexOwner(iter->Target)) || !helper) &&
vertex > iter->Target))
{
this->inc();
}
}
}
}
else
{
iter = nullptr;
}
}
RecalculateEdge();
}
private:
const vtkEdgeType &dereference() const
{
assert(iter);
return edge;
}
bool equal(const vtk_edge_iterator &other) const
{
return vertex == other.vertex && iter == other.iter;
}
void increment()
{
inc();
if (!directed)
{
vtkIdType myRank = -1;
vtkDistributedGraphHelper *helper =
this->graph ? this->graph->GetDistributedGraphHelper() : nullptr;
if (helper)
{
myRank = this->graph->GetInformation()->Get(vtkDataObject::DATA_PIECE_NUMBER());
}
while (iter != nullptr &&
( // Skip non-local edges
(helper && helper->GetEdgeOwner(iter->Id) != myRank)
// Skip entirely-local edges where Source > Target
|| (((helper && myRank == helper->GetVertexOwner(iter->Target)) || !helper) &&
vertex > iter->Target)))
{
inc();
}
}
RecalculateEdge();
}
void inc()
{
++iter;
if (iter == end)
{
// Find a vertex with nonzero out degree.
++vertex;
while (vertex < lastVertex && this->graph->GetOutDegree(vertex) == 0)
{
++vertex;
}
if (vertex < lastVertex)
{
vtkIdType nedges;
graph->GetOutEdges(vertex, iter, nedges);
end = iter + nedges;
}
else
{
iter = nullptr;
}
}
}
void RecalculateEdge()
{
if (iter)
{
edge = vtkEdgeType(vertex, iter->Target, iter->Id);
}
}
bool directed;
vtkIdType vertex;
vtkIdType lastVertex;
const vtkOutEdgeType *iter;
const vtkOutEdgeType *end;
vtkGraph *graph;
vtkEdgeType edge;
friend class iterator_core_access;
};
class vtk_out_edge_pointer_iterator
: public iterator_facade<vtk_out_edge_pointer_iterator, vtkEdgeType, bidirectional_traversal_tag,
const vtkEdgeType &, ptrdiff_t>
{
public:
explicit vtk_out_edge_pointer_iterator(vtkGraph *g = nullptr, vtkIdType v = 0, bool end = false)
: vertex(v), iter(nullptr)
{
if (g)
{
vtkIdType nedges;
g->GetOutEdges(vertex, iter, nedges);
if (end)
{
iter += nedges;
}
}
RecalculateEdge();
}
private:
const vtkEdgeType &dereference() const
{
assert(iter);
return edge;
}
bool equal(const vtk_out_edge_pointer_iterator &other) const { return iter == other.iter; }
void increment()
{
iter++;
RecalculateEdge();
}
void decrement()
{
iter--;
RecalculateEdge();
}
void RecalculateEdge()
{
if (iter)
{
edge = vtkEdgeType(vertex, iter->Target, iter->Id);
}
}
vtkIdType vertex;
const vtkOutEdgeType *iter;
vtkEdgeType edge;
friend class iterator_core_access;
};
class vtk_in_edge_pointer_iterator
: public iterator_facade<vtk_in_edge_pointer_iterator, vtkEdgeType, bidirectional_traversal_tag,
const vtkEdgeType &, ptrdiff_t>
{
public:
explicit vtk_in_edge_pointer_iterator(vtkGraph *g = nullptr, vtkIdType v = 0, bool end = false)
: vertex(v), iter(nullptr)
{
if (g)
{
vtkIdType nedges;
g->GetInEdges(vertex, iter, nedges);
if (end)
{
iter += nedges;
}
}
RecalculateEdge();
}
private:
const vtkEdgeType &dereference() const
{
assert(iter);
return edge;
}
bool equal(const vtk_in_edge_pointer_iterator &other) const { return iter == other.iter; }
void increment()
{
iter++;
RecalculateEdge();
}
void decrement()
{
iter--;
RecalculateEdge();
}
void RecalculateEdge()
{
if (iter)
{
edge = vtkEdgeType(iter->Source, vertex, iter->Id);
}
}
vtkIdType vertex;
const vtkInEdgeType *iter;
vtkEdgeType edge;
friend class iterator_core_access;
};
//===========================================================================
// vtkGraph
// VertexAndEdgeListGraphConcept
// BidirectionalGraphConcept
// AdjacencyGraphConcept
struct vtkGraph_traversal_category
: public virtual bidirectional_graph_tag,
public virtual edge_list_graph_tag,
public virtual vertex_list_graph_tag,
public virtual adjacency_graph_tag
{
};
template <>
struct graph_traits<vtkGraph *>
{
typedef vtkIdType vertex_descriptor;
static vertex_descriptor null_vertex() { return -1; }
typedef vtkEdgeType edge_descriptor;
static edge_descriptor null_edge() { return vtkEdgeType(-1, -1, -1); }
typedef vtk_out_edge_pointer_iterator out_edge_iterator;
typedef vtk_in_edge_pointer_iterator in_edge_iterator;
typedef vtk_vertex_iterator vertex_iterator;
typedef vtk_edge_iterator edge_iterator;
typedef allow_parallel_edge_tag edge_parallel_category;
typedef vtkGraph_traversal_category traversal_category;
typedef vtkIdType vertices_size_type;
typedef vtkIdType edges_size_type;
typedef vtkIdType degree_size_type;
typedef adjacency_iterator_generator<vtkGraph *, vertex_descriptor, out_edge_iterator>::type
adjacency_iterator;
};
#if BOOST_VERSION >= 104500
template <>
struct graph_property_type<vtkGraph *>
{
typedef no_property type;
};
#endif
template <>
struct vertex_property_type<vtkGraph *>
{
typedef no_property type;
};
template <>
struct edge_property_type<vtkGraph *>
{
typedef no_property type;
};
#if BOOST_VERSION >= 104500
template <>
struct graph_bundle_type<vtkGraph *>
{
typedef no_property type;
};
#endif
template <>
struct vertex_bundle_type<vtkGraph *>
{
typedef no_property type;
};
template <>
struct edge_bundle_type<vtkGraph *>
{
typedef no_property type;
};
inline bool has_no_edges(vtkGraph *g)
{
return ((g->GetNumberOfEdges() > 0) ? false : true);
}
inline void remove_edge(graph_traits<vtkGraph *>::edge_descriptor e, vtkGraph *g)
{
if (vtkMutableDirectedGraph::SafeDownCast(g))
{
vtkMutableDirectedGraph::SafeDownCast(g)->RemoveEdge(e.Id);
}
else if (vtkMutableUndirectedGraph::SafeDownCast(g))
{
vtkMutableUndirectedGraph::SafeDownCast(g)->RemoveEdge(e.Id);
}
}
//===========================================================================
// vtkDirectedGraph
template <>
struct graph_traits<vtkDirectedGraph *> : graph_traits<vtkGraph *>
{
typedef directed_tag directed_category;
};
// The graph_traits for a const graph are the same as a non-const graph.
template <>
struct graph_traits<const vtkDirectedGraph *> : graph_traits<vtkDirectedGraph *>
{
};
// The graph_traits for a const graph are the same as a non-const graph.
template <>
struct graph_traits<vtkDirectedGraph *const> : graph_traits<vtkDirectedGraph *>
{
};
#if BOOST_VERSION >= 104500
// Internal graph properties
template <>
struct graph_property_type<vtkDirectedGraph *> : graph_property_type<vtkGraph *>
{
};
// Internal graph properties
template <>
struct graph_property_type<vtkDirectedGraph *const> : graph_property_type<vtkGraph *>
{
};
#endif
// Internal vertex properties
template <>
struct vertex_property_type<vtkDirectedGraph *> : vertex_property_type<vtkGraph *>
{
};
// Internal vertex properties
template <>
struct vertex_property_type<vtkDirectedGraph *const> : vertex_property_type<vtkGraph *>
{
};
// Internal edge properties
template <>
struct edge_property_type<vtkDirectedGraph *> : edge_property_type<vtkGraph *>
{
};
// Internal edge properties
template <>
struct edge_property_type<vtkDirectedGraph *const> : edge_property_type<vtkGraph *>
{
};
#if BOOST_VERSION >= 104500
// Internal graph properties
template <>
struct graph_bundle_type<vtkDirectedGraph *> : graph_bundle_type<vtkGraph *>
{
};
// Internal graph properties
template <>
struct graph_bundle_type<vtkDirectedGraph *const> : graph_bundle_type<vtkGraph *>
{
};
#endif
// Internal vertex properties
template <>
struct vertex_bundle_type<vtkDirectedGraph *> : vertex_bundle_type<vtkGraph *>
{
};
// Internal vertex properties
template <>
struct vertex_bundle_type<vtkDirectedGraph *const> : vertex_bundle_type<vtkGraph *>
{
};
// Internal edge properties
template <>
struct edge_bundle_type<vtkDirectedGraph *> : edge_bundle_type<vtkGraph *>
{
};
// Internal edge properties
template <>
struct edge_bundle_type<vtkDirectedGraph *const> : edge_bundle_type<vtkGraph *>
{
};
//===========================================================================
// vtkTree
template <>
struct graph_traits<vtkTree *> : graph_traits<vtkDirectedGraph *>
{
};
// The graph_traits for a const graph are the same as a non-const graph.
template <>
struct graph_traits<const vtkTree *> : graph_traits<vtkTree *>
{
};
// The graph_traits for a const graph are the same as a non-const graph.
template <>
struct graph_traits<vtkTree *const> : graph_traits<vtkTree *>
{
};
//===========================================================================
// vtkUndirectedGraph
template <>
struct graph_traits<vtkUndirectedGraph *> : graph_traits<vtkGraph *>
{
typedef undirected_tag directed_category;
};
// The graph_traits for a const graph are the same as a non-const graph.
template <>
struct graph_traits<const vtkUndirectedGraph *> : graph_traits<vtkUndirectedGraph *>
{
};
// The graph_traits for a const graph are the same as a non-const graph.
template <>
struct graph_traits<vtkUndirectedGraph *const> : graph_traits<vtkUndirectedGraph *>
{
};
#if BOOST_VERSION >= 104500
// Internal graph properties
template <>
struct graph_property_type<vtkUndirectedGraph *> : graph_property_type<vtkGraph *>
{
};
// Internal graph properties
template <>
struct graph_property_type<vtkUndirectedGraph *const> : graph_property_type<vtkGraph *>
{
};
#endif
// Internal vertex properties
template <>
struct vertex_property_type<vtkUndirectedGraph *> : vertex_property_type<vtkGraph *>
{
};
// Internal vertex properties
template <>
struct vertex_property_type<vtkUndirectedGraph *const> : vertex_property_type<vtkGraph *>
{
};
// Internal edge properties
template <>
struct edge_property_type<vtkUndirectedGraph *> : edge_property_type<vtkGraph *>
{
};
// Internal edge properties
template <>
struct edge_property_type<vtkUndirectedGraph *const> : edge_property_type<vtkGraph *>
{
};
#if BOOST_VERSION >= 104500
// Internal graph properties
template <>
struct graph_bundle_type<vtkUndirectedGraph *> : graph_bundle_type<vtkGraph *>
{
};
// Internal graph properties
template <>
struct graph_bundle_type<vtkUndirectedGraph *const> : graph_bundle_type<vtkGraph *>
{
};
#endif
// Internal vertex properties
template <>
struct vertex_bundle_type<vtkUndirectedGraph *> : vertex_bundle_type<vtkGraph *>
{
};
// Internal vertex properties
template <>
struct vertex_bundle_type<vtkUndirectedGraph *const> : vertex_bundle_type<vtkGraph *>
{
};
// Internal edge properties
template <>
struct edge_bundle_type<vtkUndirectedGraph *> : edge_bundle_type<vtkGraph *>
{
};
// Internal edge properties
template <>
struct edge_bundle_type<vtkUndirectedGraph *const> : edge_bundle_type<vtkGraph *>
{
};
//===========================================================================
// vtkMutableDirectedGraph
template <>
struct graph_traits<vtkMutableDirectedGraph *> : graph_traits<vtkDirectedGraph *>
{
};
// The graph_traits for a const graph are the same as a non-const graph.
template <>
struct graph_traits<const vtkMutableDirectedGraph *> : graph_traits<vtkMutableDirectedGraph *>
{
};
// The graph_traits for a const graph are the same as a non-const graph.
template <>
struct graph_traits<vtkMutableDirectedGraph *const> : graph_traits<vtkMutableDirectedGraph *>
{
};
#if BOOST_VERSION >= 104500
// Internal graph properties
template <>
struct graph_property_type<vtkMutableDirectedGraph *> : graph_property_type<vtkDirectedGraph *>
{
};
// Internal graph properties
template <>
struct graph_property_type<vtkMutableDirectedGraph *const> : graph_property_type<vtkDirectedGraph *>
{
};
#endif
// Internal vertex properties
template <>
struct vertex_property_type<vtkMutableDirectedGraph *> : vertex_property_type<vtkDirectedGraph *>
{
};
// Internal vertex properties
template <>
struct vertex_property_type<vtkMutableDirectedGraph *const>
: vertex_property_type<vtkDirectedGraph *>
{
};
// Internal edge properties
template <>
struct edge_property_type<vtkMutableDirectedGraph *> : edge_property_type<vtkDirectedGraph *>
{
};
// Internal edge properties
template <>
struct edge_property_type<vtkMutableDirectedGraph *const> : edge_property_type<vtkDirectedGraph *>
{
};
#if BOOST_VERSION >= 104500
// Internal graph properties
template <>
struct graph_bundle_type<vtkMutableDirectedGraph *> : graph_bundle_type<vtkDirectedGraph *>
{
};
// Internal graph properties
template <>
struct graph_bundle_type<vtkMutableDirectedGraph *const> : graph_bundle_type<vtkDirectedGraph *>
{
};
#endif
// Internal vertex properties
template <>
struct vertex_bundle_type<vtkMutableDirectedGraph *> : vertex_bundle_type<vtkDirectedGraph *>
{
};
// Internal vertex properties
template <>
struct vertex_bundle_type<vtkMutableDirectedGraph *const> : vertex_bundle_type<vtkDirectedGraph *>
{
};
// Internal edge properties
template <>
struct edge_bundle_type<vtkMutableDirectedGraph *> : edge_bundle_type<vtkDirectedGraph *>
{
};
// Internal edge properties
template <>
struct edge_bundle_type<vtkMutableDirectedGraph *const> : edge_bundle_type<vtkDirectedGraph *>
{
};
//===========================================================================
// vtkMutableUndirectedGraph
template <>
struct graph_traits<vtkMutableUndirectedGraph *> : graph_traits<vtkUndirectedGraph *>
{
};
// The graph_traits for a const graph are the same as a non-const graph.
template <>
struct graph_traits<const vtkMutableUndirectedGraph *> : graph_traits<vtkMutableUndirectedGraph *>
{
};
// The graph_traits for a const graph are the same as a non-const graph.
template <>
struct graph_traits<vtkMutableUndirectedGraph *const> : graph_traits<vtkMutableUndirectedGraph *>
{
};
#if BOOST_VERSION >= 104500
// Internal graph properties
template <>
struct graph_property_type<vtkMutableUndirectedGraph *> : graph_property_type<vtkUndirectedGraph *>
{
};
// Internal graph properties
template <>
struct graph_property_type<vtkMutableUndirectedGraph *const>
: graph_property_type<vtkUndirectedGraph *>
{
};
#endif
// Internal vertex properties
template <>
struct vertex_property_type<vtkMutableUndirectedGraph *> : vertex_property_type<vtkUndirectedGraph *>
{
};
// Internal vertex properties
template <>
struct vertex_property_type<vtkMutableUndirectedGraph *const>
: vertex_property_type<vtkUndirectedGraph *>
{
};
// Internal edge properties
template <>
struct edge_property_type<vtkMutableUndirectedGraph *> : edge_property_type<vtkUndirectedGraph *>
{
};
// Internal edge properties
template <>
struct edge_property_type<vtkMutableUndirectedGraph *const>
: edge_property_type<vtkUndirectedGraph *>
{
};
#if BOOST_VERSION >= 104500
// Internal graph properties
template <>
struct graph_bundle_type<vtkMutableUndirectedGraph *> : graph_bundle_type<vtkUndirectedGraph *>
{
};
// Internal graph properties
template <>
struct graph_bundle_type<vtkMutableUndirectedGraph *const> : graph_bundle_type<vtkUndirectedGraph *>
{
};
#endif
// Internal vertex properties
template <>
struct vertex_bundle_type<vtkMutableUndirectedGraph *> : vertex_bundle_type<vtkUndirectedGraph *>
{
};
// Internal vertex properties
template <>
struct vertex_bundle_type<vtkMutableUndirectedGraph *const>
: vertex_bundle_type<vtkUndirectedGraph *>
{
};
// Internal edge properties
template <>
struct edge_bundle_type<vtkMutableUndirectedGraph *> : edge_bundle_type<vtkUndirectedGraph *>
{
};
// Internal edge properties
template <>
struct edge_bundle_type<vtkMutableUndirectedGraph *const> : edge_bundle_type<vtkUndirectedGraph *>
{
};
//===========================================================================
// API implementation
template <>
class vertex_property<vtkGraph *>
{
public:
typedef vtkIdType type;
};
template <>
class edge_property<vtkGraph *>
{
public:
typedef vtkIdType type;
};
} // end namespace boost
inline boost::graph_traits<vtkGraph *>::vertex_descriptor source(
boost::graph_traits<vtkGraph *>::edge_descriptor e, vtkGraph *)
{
return e.Source;
}
inline boost::graph_traits<vtkGraph *>::vertex_descriptor target(
boost::graph_traits<vtkGraph *>::edge_descriptor e, vtkGraph *)
{
return e.Target;
}
inline std::pair<boost::graph_traits<vtkGraph *>::vertex_iterator,
boost::graph_traits<vtkGraph *>::vertex_iterator>
vertices(vtkGraph *g)
{
typedef boost::graph_traits<vtkGraph *>::vertex_iterator Iter;
vtkIdType start = 0;
if (vtkDistributedGraphHelper *helper = g->GetDistributedGraphHelper())
{
int rank = g->GetInformation()->Get(vtkDataObject::DATA_PIECE_NUMBER());
start = helper->MakeDistributedId(rank, start);
}
return std::make_pair(Iter(start), Iter(start + g->GetNumberOfVertices()));
}
inline std::pair<boost::graph_traits<vtkGraph *>::edge_iterator,
boost::graph_traits<vtkGraph *>::edge_iterator>
edges(vtkGraph *g)
{
typedef boost::graph_traits<vtkGraph *>::edge_iterator Iter;
return std::make_pair(Iter(g), Iter(g, g->GetNumberOfVertices()));
}
inline std::pair<boost::graph_traits<vtkGraph *>::out_edge_iterator,
boost::graph_traits<vtkGraph *>::out_edge_iterator>
out_edges(boost::graph_traits<vtkGraph *>::vertex_descriptor u, vtkGraph *g)
{
typedef boost::graph_traits<vtkGraph *>::out_edge_iterator Iter;
std::pair<Iter, Iter> p = std::make_pair(Iter(g, u), Iter(g, u, true));
return p;
}
inline std::pair<boost::graph_traits<vtkGraph *>::in_edge_iterator,
boost::graph_traits<vtkGraph *>::in_edge_iterator>
in_edges(boost::graph_traits<vtkGraph *>::vertex_descriptor u, vtkGraph *g)
{
typedef boost::graph_traits<vtkGraph *>::in_edge_iterator Iter;
std::pair<Iter, Iter> p = std::make_pair(Iter(g, u), Iter(g, u, true));
return p;
}
inline std::pair<boost::graph_traits<vtkGraph *>::adjacency_iterator,
boost::graph_traits<vtkGraph *>::adjacency_iterator>
adjacent_vertices(boost::graph_traits<vtkGraph *>::vertex_descriptor u, vtkGraph *g)
{
typedef boost::graph_traits<vtkGraph *>::adjacency_iterator Iter;
typedef boost::graph_traits<vtkGraph *>::out_edge_iterator OutEdgeIter;
std::pair<OutEdgeIter, OutEdgeIter> out = out_edges(u, g);
return std::make_pair(Iter(out.first, &g), Iter(out.second, &g));
}
inline boost::graph_traits<vtkGraph *>::vertices_size_type num_vertices(vtkGraph *g)
{
return g->GetNumberOfVertices();
}
inline boost::graph_traits<vtkGraph *>::edges_size_type num_edges(vtkGraph *g)
{
return g->GetNumberOfEdges();
}
inline boost::graph_traits<vtkGraph *>::degree_size_type out_degree(
boost::graph_traits<vtkGraph *>::vertex_descriptor u, vtkGraph *g)
{
return g->GetOutDegree(u);
}
inline boost::graph_traits<vtkDirectedGraph *>::degree_size_type in_degree(
boost::graph_traits<vtkDirectedGraph *>::vertex_descriptor u, vtkDirectedGraph *g)
{
return g->GetInDegree(u);
}
inline boost::graph_traits<vtkGraph *>::degree_size_type degree(
boost::graph_traits<vtkGraph *>::vertex_descriptor u, vtkGraph *g)
{
return g->GetDegree(u);
}
inline boost::graph_traits<vtkMutableDirectedGraph *>::vertex_descriptor add_vertex(
vtkMutableDirectedGraph *g)
{
return g->AddVertex();
}
inline std::pair<boost::graph_traits<vtkMutableDirectedGraph *>::edge_descriptor, bool> add_edge(
boost::graph_traits<vtkMutableDirectedGraph *>::vertex_descriptor u,
boost::graph_traits<vtkMutableDirectedGraph *>::vertex_descriptor v, vtkMutableDirectedGraph *g)
{
boost::graph_traits<vtkMutableDirectedGraph *>::edge_descriptor e = g->AddEdge(u, v);
return std::make_pair(e, true);
}
inline boost::graph_traits<vtkMutableUndirectedGraph *>::vertex_descriptor add_vertex(
vtkMutableUndirectedGraph *g)
{
return g->AddVertex();
}
inline std::pair<boost::graph_traits<vtkMutableUndirectedGraph *>::edge_descriptor, bool> add_edge(
boost::graph_traits<vtkMutableUndirectedGraph *>::vertex_descriptor u,
boost::graph_traits<vtkMutableUndirectedGraph *>::vertex_descriptor v,
vtkMutableUndirectedGraph *g)
{
boost::graph_traits<vtkMutableUndirectedGraph *>::edge_descriptor e = g->AddEdge(u, v);
return std::make_pair(e, true);
}
namespace boost
{
//===========================================================================
// An edge map for vtkGraph.
// This is a common input needed for algorithms.
struct vtkGraphEdgeMap
{
};
template <>
struct property_traits<vtkGraphEdgeMap>
{
typedef vtkIdType value_type;
typedef vtkIdType reference;
typedef vtkEdgeType key_type;
typedef readable_property_map_tag category;
};
inline property_traits<vtkGraphEdgeMap>::reference get(
vtkGraphEdgeMap vtkNotUsed(arr), property_traits<vtkGraphEdgeMap>::key_type key)
{
return key.Id;
}
//===========================================================================
// Helper for vtkGraph edge property maps
// Automatically converts boost edge ids to vtkGraph edge ids.
template <typename PMap>
class vtkGraphEdgePropertyMapHelper
{
public:
vtkGraphEdgePropertyMapHelper(PMap m)
: pmap(m)
{
}
PMap pmap;
typedef typename property_traits<PMap>::value_type value_type;
typedef typename property_traits<PMap>::reference reference;
typedef vtkEdgeType key_type;
typedef typename property_traits<PMap>::category category;
reference operator[](const key_type &key) const { return get(pmap, key.Id); }
};
template <typename PMap>
inline typename property_traits<PMap>::reference get(
vtkGraphEdgePropertyMapHelper<PMap> helper, vtkEdgeType key)
{
return get(helper.pmap, key.Id);
}
template <typename PMap>
inline void put(vtkGraphEdgePropertyMapHelper<PMap> helper, vtkEdgeType key,
const typename property_traits<PMap>::value_type &value)
{
put(helper.pmap, key.Id, value);
}
//===========================================================================
// Helper for vtkGraph vertex property maps
// Automatically converts boost vertex ids to vtkGraph vertex ids.
template <typename PMap>
class vtkGraphVertexPropertyMapHelper
{
public:
vtkGraphVertexPropertyMapHelper(PMap m)
: pmap(m)
{
}
PMap pmap;
typedef typename property_traits<PMap>::value_type value_type;
typedef typename property_traits<PMap>::reference reference;
typedef vtkIdType key_type;
typedef typename property_traits<PMap>::category category;
reference operator[](const key_type &key) const { return get(pmap, key); }
};
template <typename PMap>
inline typename property_traits<PMap>::reference get(
vtkGraphVertexPropertyMapHelper<PMap> helper, vtkIdType key)
{
return get(helper.pmap, key);
}
template <typename PMap>
inline void put(vtkGraphVertexPropertyMapHelper<PMap> helper, vtkIdType key,
const typename property_traits<PMap>::value_type &value)
{
put(helper.pmap, key, value);
}
//===========================================================================
// An index map for vtkGraph
// This is a common input needed for algorithms
struct vtkGraphIndexMap
{
};
template <>
struct property_traits<vtkGraphIndexMap>
{
typedef vtkIdType value_type;
typedef vtkIdType reference;
typedef vtkIdType key_type;
typedef readable_property_map_tag category;
};
inline property_traits<vtkGraphIndexMap>::reference get(
vtkGraphIndexMap vtkNotUsed(arr), property_traits<vtkGraphIndexMap>::key_type key)
{
return key;
}
//===========================================================================
// Helper for vtkGraph property maps
// Automatically multiplies the property value by some value (default 1)
template <typename PMap>
class vtkGraphPropertyMapMultiplier
{
public:
vtkGraphPropertyMapMultiplier(PMap m, float multi = 1)
: pmap(m), multiplier(multi)
{
}
PMap pmap;
float multiplier;
typedef typename property_traits<PMap>::value_type value_type;
typedef typename property_traits<PMap>::reference reference;
typedef typename property_traits<PMap>::key_type key_type;
typedef typename property_traits<PMap>::category category;
};
template <typename PMap>
inline typename property_traits<PMap>::reference get(
vtkGraphPropertyMapMultiplier<PMap> multi, const typename property_traits<PMap>::key_type &key)
{
return multi.multiplier * get(multi.pmap, key);
}
template <typename PMap>
inline void put(vtkGraphPropertyMapMultiplier<PMap> multi,
const typename property_traits<PMap>::key_type &key,
const typename property_traits<PMap>::value_type &value)
{
put(multi.pmap, key, value);
}
// Allow algorithms to automatically extract vtkGraphIndexMap from a
// VTK graph
template <>
struct property_map<vtkGraph *, vertex_index_t>
{
typedef vtkGraphIndexMap type;
typedef vtkGraphIndexMap const_type;
};
template <>
struct property_map<vtkDirectedGraph *, vertex_index_t> : property_map<vtkGraph *, vertex_index_t>
{
};
template <>
struct property_map<vtkUndirectedGraph *, vertex_index_t> : property_map<vtkGraph *, vertex_index_t>
{
};
inline vtkGraphIndexMap get(vertex_index_t, vtkGraph *)
{
return vtkGraphIndexMap();
}
template <>
struct property_map<vtkGraph *, edge_index_t>
{
typedef vtkGraphIndexMap type;
typedef vtkGraphIndexMap const_type;
};
template <>
struct property_map<vtkDirectedGraph *, edge_index_t> : property_map<vtkGraph *, edge_index_t>
{
};
template <>
struct property_map<vtkUndirectedGraph *, edge_index_t> : property_map<vtkGraph *, edge_index_t>
{
};
inline vtkGraphIndexMap get(edge_index_t, vtkGraph *)
{
return vtkGraphIndexMap();
}
// property_map specializations for const-qualified graphs
template <>
struct property_map<vtkDirectedGraph *const, vertex_index_t>
: property_map<vtkDirectedGraph *, vertex_index_t>
{
};
template <>
struct property_map<vtkUndirectedGraph *const, vertex_index_t>
: property_map<vtkUndirectedGraph *, vertex_index_t>
{
};
template <>
struct property_map<vtkDirectedGraph *const, edge_index_t>
: property_map<vtkDirectedGraph *, edge_index_t>
{
};
template <>
struct property_map<vtkUndirectedGraph *const, edge_index_t>
: property_map<vtkUndirectedGraph *, edge_index_t>
{
};
} // namespace boost
#if BOOST_VERSION > 104000
#include <boost/property_map/vector_property_map.hpp>
#else
#include <boost/vector_property_map.hpp>
#endif
#endif // vtkBoostGraphAdapter_h
// VTK-HeaderTest-Exclude: vtkBoostGraphAdapter.h
\ No newline at end of file
#include "vtkPolyDataToGraph.h"
// for testing only
#include "vtkXMLPolyDataWriter.h"
#include <vtkGraphToPolyData.h>
#include <vtkFloatArray.h>
#include <vtkPointData.h>
#include <vtkExtractEdges.h>
#include <vtkLine.h>
#include <vtkObjectFactory.h>
#include <vtkStreamingDemandDrivenPipeline.h>
#include <vtkInformationVector.h>
#include <vtkInformation.h>
#include <vtkMutableUndirectedGraph.h>
#include <vtkAdjacentVertexIterator.h>
#include <vtkPolyData.h>
#include <vtkImageData.h>
#include <vtkSmartPointer.h>
int vtkPolyDataToGraph::RequestDataObject(vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
{
vtkMutableUndirectedGraph *output = 0;
output = vtkMutableUndirectedGraph::New();
this->GetExecutive()->SetOutputData(0, output);
output->Delete();
return 1;
}
/*
//it works with or without this re-implementation
int vtkMeshToGraph::FillOutputPortInformation(
int vtkNotUsed(port), vtkInformation* info)
{
// now add our info
info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkMutableUndirectedGraph");
return 1;
}
*/
//----------------------------------------------------------------------------
int vtkPolyDataToGraph::FillInputPortInformation(
int vtkNotUsed(port), vtkInformation *info)
{
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
return 1;
}
int vtkPolyDataToGraph::RequestData(
vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *outputVector)
{
// get the input and ouptut
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
// vtkPolyData *input = vtkPolyData::SafeDownCast(
vtkPolyData *input = vtkPolyData::SafeDownCast(
inInfo->Get(vtkDataObject::DATA_OBJECT()));
std::cout << "vtkPolyDataToGraph: Input has " << input->GetNumberOfPoints() << " points." << std::endl;
vtkInformation *outInfo = outputVector->GetInformationObject(0);
vtkMutableUndirectedGraph *output = vtkMutableUndirectedGraph::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
// add a vertex for every point
for (vtkIdType i = 0; i < input->GetNumberOfPoints(); i++)
{
output->AddVertex();
}
// output->GetVertexData()->ShallowCopy(input->GetPointData());
output->GetVertexData()->PassData(input->GetPointData());
// add the edge between every point and every point connected to it (do not allow duplicates)
for (vtkIdType i = 0; i < input->GetNumberOfPoints(); i++)
{
vtkSmartPointer<vtkIdList> idList =
vtkSmartPointer<vtkIdList>::New();
this->GetConnectedVertices(input, i, idList);
for (vtkIdType id = 0; id < idList->GetNumberOfIds(); id++)
{
if (!EdgeExists(output, i, idList->GetId(id)))
{
output->AddEdge(i, idList->GetId(id));
}
}
}
output->SetPoints(input->GetPoints());
{
vtkSmartPointer<vtkMutableUndirectedGraph> outputGraph =
vtkSmartPointer<vtkMutableUndirectedGraph>::New();
outputGraph->ShallowCopy(output);
vtkSmartPointer<vtkGraphToPolyData> graphToPolyData =
vtkSmartPointer<vtkGraphToPolyData>::New();
graphToPolyData->SetInputData(outputGraph);
graphToPolyData->Update();
vtkSmartPointer<vtkXMLPolyDataWriter> writer =
vtkSmartPointer<vtkXMLPolyDataWriter>::New();
writer->SetFileName("MeshToGraphOutput.vtp");
writer->SetInputConnection(graphToPolyData->GetOutputPort());
writer->Write();
}
return 1;
}
bool vtkPolyDataToGraph::EdgeExists(vtkSmartPointer<vtkGraph> g, int pointID, int neighborID)
{
// check if the edge already exists
vtkSmartPointer<vtkAdjacentVertexIterator> iterator =
vtkSmartPointer<vtkAdjacentVertexIterator>::New();
g->GetAdjacentVertices(pointID, iterator);
bool edgeExists = false;
while (iterator->HasNext())
{
if (iterator->Next() == neighborID)
{
edgeExists = true;
break;
}
}
return edgeExists;
}
void vtkPolyDataToGraph::GetConnectedVertices(vtkSmartPointer<vtkPolyData> mesh, int seed, vtkSmartPointer<vtkIdList> connectedVertices)
{
// get all cells that vertex 'seed' is a part of
vtkSmartPointer<vtkIdList> cellIdList =
vtkSmartPointer<vtkIdList>::New();
mesh->GetPointCells(seed, cellIdList);
// cout << "There are " << cellIdList->GetNumberOfIds() << " cells that use point " << seed << endl;
// loop through all the cells that use the seed point
for (vtkIdType i = 0; i < cellIdList->GetNumberOfIds(); i++)
{
vtkCell *cell = mesh->GetCell(cellIdList->GetId(i));
// cout << "The cell has " << cell->GetNumberOfEdges() << " edges." << endl;
// if the cell doesn't have any edges, it is a line
if (cell->GetNumberOfEdges() <= 0)
{
// vtkLine* line = vtkLine::SafeDownCast(input->GetCell(i));
vtkLine *line = vtkLine::SafeDownCast(mesh->GetCell(cellIdList->GetId(i)));
// if the cell didn't have any edges, and it is not a line, it must be a vertex, so skip it
if (!line)
{
continue;
}
else
{
int p0 = line->GetPointId(0);
int p1 = line->GetPointId(1);
if (p0 == seed)
{
connectedVertices->InsertNextId(p1);
}
else
{
connectedVertices->InsertNextId(p0);
}
}
continue;
}
// if we get to here, the cell is a polygon, so extract its border edges
for (vtkIdType e = 0; e < cell->GetNumberOfEdges(); e++)
{
vtkCell *edge = cell->GetEdge(e);
vtkIdList *pointIdList = edge->GetPointIds();
// cout << "This cell uses " << pointIdList->GetNumberOfIds() << " points" << endl;
/*
for(vtkIdType p = 0; p < pointIdList->GetNumberOfIds(); p++)
{
cout << "Edge " << i << " uses point " << pointIdList->GetId(p) << endl;
}
*/
if (pointIdList->GetId(0) == seed || pointIdList->GetId(1) == seed)
{
if (pointIdList->GetId(0) == seed)
{
connectedVertices->InsertNextId(pointIdList->GetId(1));
}
else
{
connectedVertices->InsertNextId(pointIdList->GetId(0));
}
}
}
}
// cout << "There are " << connectedVertices->GetNumberOfIds() << " points connected to point " << seed << endl;
}
\ No newline at end of file
// This class converts all of the points in a vtkPolyData into vertices in a vtkGraph, and all
// "edges" in a vtkPolyData (borders of polygons and vtkLines) into edges in a vtkGraph
#ifndef __vtkPolyDataToGraph_h
#define __vtkPolyDataToGraph_h
#include <vtkGraphAlgorithm.h>
#include <vtkSmartPointer.h>
class vtkPolyData;
class vtkIdList;
class vtkPolyDataToGraph : public vtkGraphAlgorithm
{
public:
static vtkPolyDataToGraph *New();
protected:
vtkPolyDataToGraph() {}
~vtkPolyDataToGraph() {}
virtual int FillInputPortInformation(int port, vtkInformation *info);
int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
int RequestDataObject(vtkInformation *vtkNotUsed(request),
vtkInformationVector **inputVector,
vtkInformationVector *outputVector);
private:
vtkPolyDataToGraph(const vtkPolyDataToGraph &); // Not implemented.
void operator=(const vtkPolyDataToGraph &); // Not implemented.
// should not be part of this class
bool EdgeExists(vtkSmartPointer<vtkGraph> g, int pointID, int neighborID);
void GetConnectedVertices(vtkSmartPointer<vtkPolyData> mesh, int seed, vtkSmartPointer<vtkIdList> connectedVertices);
};
#endif
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment