#include "vtkVersion.h"
#include <vtkCellArray.h>
#include <vtkSmartPointer.h>
#include <vtkUnstructuredGrid.h>
#include <vtkXMLUnstructuredGridWriter.h>
static MeshType::Pointer
CreateMeshWithEdges();
static void
ConvertMeshToUnstructuredGrid(MeshType::Pointer, vtkUnstructuredGrid *);
class VisitVTKCellsClass
{
vtkCellArray * m_Cells;
int * m_LastCell;
int * m_TypeArray;
public:
void
SetCellArray(vtkCellArray * a)
{
m_Cells = a;
}
void
SetCellCounter(int * i)
{
m_LastCell = i;
}
void
SetTypeArray(int * i)
{
m_TypeArray = i;
}
void
Visit(unsigned long, floatTriangleCell * t)
{
m_Cells->InsertNextCell(3, (vtkIdType *)t->PointIdsBegin());
m_TypeArray[*m_LastCell] = VTK_TRIANGLE;
(*m_LastCell)++;
}
void
Visit(unsigned long, floatQuadrilateralCell * t)
{
m_Cells->InsertNextCell(4, (vtkIdType *)t->PointIdsBegin());
m_TypeArray[*m_LastCell] = VTK_QUAD;
(*m_LastCell)++;
}
void
Visit(unsigned long, floatLineCell * t)
{
m_Cells->InsertNextCell(2, (vtkIdType *)t->PointIdsBegin());
m_TypeArray[*m_LastCell] = VTK_LINE;
(*m_LastCell)++;
}
};
int
main(int, char *[])
{
MeshType::Pointer mesh = CreateMeshWithEdges();
vtkSmartPointer<vtkUnstructuredGrid> unstructuredGrid = vtkSmartPointer<vtkUnstructuredGrid>::New();
ConvertMeshToUnstructuredGrid(mesh, unstructuredGrid);
vtkSmartPointer<vtkXMLUnstructuredGridWriter> writer = vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
writer->SetFileName("output.vtu");
#if VTK_MAJOR_VERSION <= 5
writer->SetInputConnection(unstructuredGrid->GetProducerPort());
#else
writer->SetInputData(unstructuredGrid);
#endif
writer->Write();
return EXIT_SUCCESS;
}
MeshType::Pointer
CreateMeshWithEdges()
{
MeshType::Pointer mesh = MeshType::New();
p0[0] = -1.0;
p0[1] = -1.0;
p0[2] = 0.0;
p1[0] = 1.0;
p1[1] = -1.0;
p1[2] = 0.0;
p2[0] = 1.0;
p2[1] = 1.0;
p2[2] = 0.0;
p3[0] = 1.0;
p3[1] = 1.0;
p3[2] = 1.0;
mesh->SetPoint(0, p0);
mesh->SetPoint(1, p1);
mesh->SetPoint(2, p2);
mesh->SetPoint(3, p3);
using CellAutoPointer = MeshType::CellType::CellAutoPointer;
CellAutoPointer line0;
line0.TakeOwnership(new LineType);
line0->SetPointId(1, 1);
mesh->SetCell(0, line0);
CellAutoPointer line1;
line1.TakeOwnership(new LineType);
line1->SetPointId(0, 1);
line1->SetPointId(1, 2);
mesh->SetCell(1, line1);
CellAutoPointer line2;
line2.TakeOwnership(new LineType);
line2->SetPointId(0, 2);
line2->SetPointId(1, 3);
mesh->SetCell(2, line2);
return mesh;
}
void
ConvertMeshToUnstructuredGrid(MeshType::Pointer mesh, vtkUnstructuredGrid * unstructuredGrid)
{
int numPoints = mesh->GetNumberOfPoints();
if (numPoints == 0)
{
mesh->Print(std::cerr);
std::cerr << "no points in Grid " << std::endl;
exit(-1);
}
vtkPoints * vpoints = vtkPoints::New();
vpoints->SetNumberOfPoints(numPoints);
MeshType::PointsContainer::Pointer points = mesh->GetPoints();
vtkIdType VTKId = 0;
std::map<vtkIdType, int> IndexMap;
for (MeshType::PointsContainer::Iterator i = points->Begin(); i != points->End(); ++i, VTKId++)
{
IndexMap[VTKId] = i->Index();
vpoints->SetPoint(VTKId, const_cast<float *>(i->Value().GetDataPointer()));
}
unstructuredGrid->SetPoints(vpoints);
int vtkCellCount = 0;
int numCells = mesh->GetNumberOfCells();
auto * types = new int[numCells];
vtkCellArray * cells = vtkCellArray::New();
cells->EstimateSize(numCells, 4);
float,
MeshType::CellTraits,
VisitVTKCellsClass>;
LineVisitor::Pointer lv = LineVisitor::New();
lv->SetTypeArray(types);
lv->SetCellCounter(&vtkCellCount);
lv->SetCellArray(cells);
float,
MeshType::CellTraits,
VisitVTKCellsClass>;
TriangleVisitor::Pointer tv = TriangleVisitor::New();
tv->SetTypeArray(types);
tv->SetCellCounter(&vtkCellCount);
tv->SetCellArray(cells);
float,
MeshType::CellTraits,
VisitVTKCellsClass>;
QuadrilateralVisitor::Pointer qv = QuadrilateralVisitor::New();
qv->SetTypeArray(types);
qv->SetCellCounter(&vtkCellCount);
qv->SetCellArray(cells);
MeshType::CellType::MultiVisitor::Pointer mv = MeshType::CellType::MultiVisitor::New();
mv->AddVisitor(tv);
mv->AddVisitor(qv);
mv->AddVisitor(lv);
mesh->Accept(mv);
unstructuredGrid->SetCells(types, cells);
std::cout << "Unstructured grid has " << unstructuredGrid->GetNumberOfCells() << " cells." << std::endl;
cells->Delete();
vpoints->Delete();
}