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) ...@@ -2,22 +2,37 @@ cmake_minimum_required(VERSION 3.8)
# name of the project # name of the project
project(projet-stage) project(projet-stage)
set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD 11)
# Search for library TTK/VTK
find_package(TTKVTK REQUIRED) find_package(TTKVTK REQUIRED)
# Add src files
add_executable(projet-stage main.cpp operation_mesh.cpp vtkOFFReader.cxx) add_executable(projet-stage main.cpp operation_mesh.cpp vtkOFFReader.cxx)
target_link_libraries(projet-stage target_link_libraries(projet-stage
PUBLIC PUBLIC
ttk::vtk::ttkAll ttk::vtk::ttkAll
PRIVATE ${VTK_LIBRARIES} 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( vtk_module_autoinit(
TARGETS projet-stage TARGETS projet-stage vpt2dot
MODULES ${VTK_LIBRARIES} 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;
}
This diff is collapsed.
#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