Commit 08dae251 authored by Timothee Chabat's avatar Timothee Chabat
Browse files

WIP Mulitblock support for Gmsh Writer

 - Topology is exporting correctly
parent 93e89f4a
......@@ -98,7 +98,7 @@
<Group name="sources"/>
<Group name="filters"/>
</ProxyGroupDomain>
<DataTypeDomain name="input_type" composite_data_supported="0">
<DataTypeDomain name="input_type" composite_data_supported="1">
<DataType value="vtkUnstructuredGrid"/>
</DataTypeDomain>
</InputProperty>
......
......@@ -31,6 +31,9 @@
#include "vtkUnsignedCharArray.h"
#include "vtkUnstructuredGrid.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkCompositeDataIterator.h"
#include "gmsh.h"
#include <numeric>
......@@ -39,42 +42,61 @@
#include <vector>
//-----------------------------------------------------------------------------
struct GmshWriterInternal
struct MPhysicalGroup
{
int Dimension = 3;
int ModelTag = -1;
std::vector<std::string> NodeViews;
std::vector<std::string> CellViews;
std::string ModelName;
std::string Name = "";
int Dimension = -1;
int Entity = -1;
vtkUnstructuredGrid* Grid = nullptr;
vtkIdType CellOffset = 0;
vtkIdType NodeOffset = 0;
};
std::vector<std::size_t> CellDataIndex;
struct GmshWriterInternal
{
std::string ModelName = "PVModel";
std::vector<MPhysicalGroup> PhysicalGroups;
// Initialize sum to 1 because Gmsh tags begin at 1
vtkIdType NodeOffsetSum = 1;
vtkIdType CellOffsetSum = 1;
double* TimeSteps = nullptr;
unsigned int NumberOfTimeSteps = 0;
unsigned int CurrentTimeStep = 0;
double CurrentTime = 0.0;
vtkUnstructuredGrid* Input = nullptr;
static const std::unordered_map<unsigned char, GmshPrimitive> TRANSLATE_CELLS_TYPE;
static constexpr unsigned char MAX_TAG = 15u;
};
const std::unordered_map<unsigned char, GmshPrimitive> GmshWriterInternal::TRANSLATE_CELLS_TYPE = {
{ VTK_VERTEX, GmshPrimitive::POINT }, { VTK_LINE, GmshPrimitive::LINE },
{ VTK_POLY_LINE, GmshPrimitive::Unsupported }, { VTK_TRIANGLE, GmshPrimitive::TRIANGLE },
{ VTK_TRIANGLE_STRIP, GmshPrimitive::Unsupported }, { VTK_POLYGON, GmshPrimitive::Unsupported },
{ VTK_PIXEL, GmshPrimitive::QUAD }, { VTK_QUAD, GmshPrimitive::QUAD },
{ VTK_TETRA, GmshPrimitive::TETRA }, { VTK_VOXEL, GmshPrimitive::HEXA },
{ VTK_HEXAHEDRON, GmshPrimitive::HEXA }, { VTK_WEDGE, GmshPrimitive::PRISM },
{ VTK_PYRAMID, GmshPrimitive::PYRAMID }
};
//-----------------------------------------------------------------------------
namespace
{
static constexpr unsigned char MAX_TYPE = 15u;
typedef std::array<std::vector<std::size_t>, ::MAX_TYPE> ArrayVectorType;
// Associate a VTK type to a Gmsh type and its topological dimension.
// If dimension < 0 or GmshPrimitive >= MAX_TYPE, type is not supported.
// If dimension > 0 and GmshPrimitive == Unsupported, the cell first needs
// to be triangulated in order to be supported by Gmsh.
// clang-format off
static constexpr std::array<std::pair<GmshPrimitive, char>, MAX_TYPE> TRANSLATE_CELLS_TYPE = {
{ { GmshPrimitive::Unsupported, -1 } // VTK_EMPTY_CELL
, { GmshPrimitive::POINT, 0 } // VTK_VERTEX
, { GmshPrimitive::Unsupported, -1 } // VTK_POLY_VERTEX
, { GmshPrimitive::LINE, 1 } // VTK_LINE
, { GmshPrimitive::Unsupported, 1 } // VTK_POLY_LINE
, { GmshPrimitive::TRIANGLE, 2 } // VTK_TRIANGLE
, { GmshPrimitive::Unsupported, 2 } // VTK_TRIANGLE_STRIP
, { GmshPrimitive::Unsupported, 2 } // VTK_POLYGON
, { GmshPrimitive::QUAD, 2 } // VTK_PIXEL
, { GmshPrimitive::QUAD, 2 } // VTK_QUAD
, { GmshPrimitive::TETRA, 3 } // VTK_TETRA
, { GmshPrimitive::HEXA, 3 } // VTK_VOXEL
, { GmshPrimitive::HEXA, 3 } // VTK_HEXAHEDRON
, { GmshPrimitive::PRISM, 3 } // VTK_WEDGE
, { GmshPrimitive::PYRAMID, 3 } // VTK_PYRAMID
}};
// clang-format on
// Reorder voxel vertices as hexahedron vertices to support it with Gmsh.
// `cellArray` contains a lot a cell vertices, while `idx` is the index of the
// `cellArray` contains every cell vertices, while `idx` is the index of the
// first vertex for the current voxel
void OrderVoxel(std::vector<std::size_t>& cellArray, std::size_t idx)
{
......@@ -83,7 +105,7 @@ void OrderVoxel(std::vector<std::size_t>& cellArray, std::size_t idx)
}
// Reorder pixel vertices as quad vertices to support it with Gmsh.
// `cellArray` contains a lot a cell vertices, while `idx` is the index of the
// `cellArray` contains every cell vertices, while `idx` is the index of the
// first vertex for the current pixel
void OrderPixel(std::vector<std::size_t>& cellArray, std::size_t idx)
{
......@@ -91,53 +113,50 @@ void OrderPixel(std::vector<std::size_t>& cellArray, std::size_t idx)
}
// Transform VTK types not supported by Gmsh (like triange strips or polylines)
// as simpler primitives.
void AddTriangulatedCell(std::vector<std::size_t>& nodeTags,
std::vector<std::size_t>& newTypeIndexes, const std::vector<std::size_t>& oldTypeIndexes,
GmshWriterInternal* internal, vtkIdType& cellCounterId, const int dim)
// as simpler primitives by triangulating them.
vtkIdType AddTriangulatedCell(const MPhysicalGroup& group, std::vector<std::size_t>& gmshNodeTags,
const std::vector<std::size_t>& vtkCellToTranform, const int dim)
{
for (std::size_t idx : oldTypeIndexes)
vtkIdType createdCell = 0;
vtkNew<vtkIdList> nodeIds;
vtkNew<vtkPoints> dummy;
for (std::size_t idx : vtkCellToTranform)
{
const std::size_t vtkIdx = idx - 1u;
vtkCell* cell = internal->Input->GetCell(vtkIdx);
vtkNew<vtkIdList> ptIds;
vtkNew<vtkPoints> points;
cell->Triangulate(0, ptIds, points);
const vtkIdType numIds = ptIds->GetNumberOfIds();
for (vtkIdType i = 0; i < numIds; ++i)
{
nodeTags.push_back(ptIds->GetId(i) + 1);
}
for (int i = 0; i < (numIds / dim); ++i)
vtkCell* cell = group.Grid->GetCell(idx);
cell->Triangulate(0, nodeIds, dummy);
const vtkIdType numNodes = nodeIds->GetNumberOfIds();
for (vtkIdType i = 0; i < numNodes; ++i)
{
newTypeIndexes.push_back(cellCounterId);
internal->CellDataIndex.push_back(vtkIdx);
++cellCounterId;
gmshNodeTags.push_back(nodeIds->GetId(i) + group.NodeOffset);
}
createdCell += (numNodes / dim);
}
return createdCell;
}
// Add every supported VTK cells in the gmsh model by type.
void FillCells(const int modelTag, GmshWriterInternal* internal,
std::vector<std::size_t> idxPerType[], vtkUnstructuredGrid* input, vtkDataArray* offsets,
vtkDataArray* connectivity)
vtkIdType FillCells(const MPhysicalGroup& group, const ArrayVectorType& vtkCellIdxsPerType)
{
vtkIdType cellCounterId = 1;
internal->CellDataIndex.clear();
internal->CellDataIndex.reserve(input->GetNumberOfCells());
vtkDataArray* offsets = group.Grid->GetCells()->GetOffsetsArray();
vtkDataArray* connectivity = group.Grid->GetCells()->GetConnectivityArray();
for (unsigned char currentType = 1; currentType < GmshWriterInternal::MAX_TAG; ++currentType)
vtkIdType numCreatedCell = 0;
for (unsigned char currentType = 1; currentType < MAX_TYPE; ++currentType)
{
std::vector<std::size_t>& indexes = idxPerType[currentType];
if (indexes.empty())
const std::vector<std::size_t>& vtkCellIdxs = vtkCellIdxsPerType[currentType];
if (vtkCellIdxs.empty())
{
continue;
}
char gmshType =
static_cast<char>(GmshWriterInternal::TRANSLATE_CELLS_TYPE.find(currentType)->second);
// If this type is not natively supported, it will be transleted in either lines or triangles
const char gmshType =
static_cast<char>(TRANSLATE_CELLS_TYPE[currentType].first);
// Type not natively supported, it will be triangulated later
if (gmshType < 0)
{
continue;
......@@ -145,15 +164,15 @@ void FillCells(const int modelTag, GmshWriterInternal* internal,
// Add cells for this vtk type
std::vector<std::size_t> gmshNodeTags;
for (std::size_t idx : indexes)
for (std::size_t index : vtkCellIdxs)
{
const std::size_t vtkIdx = idx - 1;
const int beginCell = gmshNodeTags.size();
long offsetBegin = static_cast<long>(*offsets->GetTuple(vtkIdx));
long offsetEnd = static_cast<long>(*offsets->GetTuple(vtkIdx + 1));
const long offsetBegin = static_cast<long>(*offsets->GetTuple(index));
const long offsetEnd = static_cast<long>(*offsets->GetTuple(index + 1));
for (unsigned int j = offsetBegin; j < offsetEnd; ++j)
{
gmshNodeTags.push_back(static_cast<long>(*connectivity->GetTuple(j)) + 1u);
const std::size_t vtkNodeIndex = static_cast<std::size_t>(*connectivity->GetTuple(j));
gmshNodeTags.push_back(vtkNodeIndex + group.NodeOffset);
}
// Ordering if needed
......@@ -165,32 +184,33 @@ void FillCells(const int modelTag, GmshWriterInternal* internal,
{
::OrderVoxel(gmshNodeTags, beginCell);
}
// Add data index
internal->CellDataIndex.push_back(vtkIdx);
}
// Generate gmsh ids
std::vector<std::size_t> gmshIds(indexes.size());
std::iota(gmshIds.begin(), gmshIds.end(), cellCounterId);
cellCounterId += gmshIds.size();
// Translate non-supported type into supported one
vtkIdType numCreatedCellFromTriangl = 0;
const vtkIdType numOfCells = vtkCellIdxs.size();
if (currentType == VTK_LINE)
{
::AddTriangulatedCell(
gmshNodeTags, gmshIds, idxPerType[VTK_POLY_LINE], internal, cellCounterId, 2);
numCreatedCellFromTriangl += ::AddTriangulatedCell(
group, gmshNodeTags, vtkCellIdxsPerType[VTK_POLY_LINE], 2);
}
else if (currentType == VTK_TRIANGLE)
{
::AddTriangulatedCell(
gmshNodeTags, gmshIds, idxPerType[VTK_TRIANGLE_STRIP], internal, cellCounterId, 3);
::AddTriangulatedCell(
gmshNodeTags, gmshIds, idxPerType[VTK_POLYGON], internal, cellCounterId, 3);
numCreatedCellFromTriangl += ::AddTriangulatedCell(
group, gmshNodeTags, vtkCellIdxsPerType[VTK_TRIANGLE_STRIP], 3);
numCreatedCellFromTriangl += ::AddTriangulatedCell(
group, gmshNodeTags, vtkCellIdxsPerType[VTK_POLYGON], 3);
}
gmsh::model::mesh::addElementsByType(modelTag, gmshType, gmshIds, gmshNodeTags);
// Generate cell gmsh ids
std::vector<std::size_t> gmshIds(numOfCells + numCreatedCellFromTriangl);
std::iota(gmshIds.begin(), gmshIds.end(), numCreatedCell + group.CellOffset);
numCreatedCell += gmshIds.size();
gmsh::model::mesh::addElementsByType(group.Entity, gmshType, gmshIds, gmshNodeTags);
}
return numCreatedCell;
}
}
......@@ -212,143 +232,90 @@ vtkGmshWriter::~vtkGmshWriter()
}
//-----------------------------------------------------------------------------
void vtkGmshWriter::LoadNodes()
int vtkGmshWriter::LoadGridIntoPhysicalGroup(vtkUnstructuredGrid* input, std::string name, int desiredDimension)
{
vtkUnstructuredGrid* input = this->Internal->Input;
// std::vector<std::size_t> vtkCellIdxsPerType[::MAX_TYPE];
::ArrayVectorType vtkCellIdxsPerType;
vtkDataArray* points = input->GetPoints()->GetData();
const vtkIdType numTuples = points->GetNumberOfTuples();
const vtkIdType numCompnt = points->GetNumberOfComponents();
std::vector<double> inlineCoords(numTuples * numCompnt);
// Store point coordinates in a structure Gmsh can understand
for (vtkIdType i = 0, counter = 0; i < numTuples; ++i)
// =================== Load Cells =========================
// Build list of gmsh indexes per type
{
for (vtkIdType j = 0; j < numCompnt; ++j)
vtkCellArray* cells = input->GetCells();
const vtkIdType numberOfCells = cells->GetNumberOfCells();
if (numberOfCells <= 0)
{
inlineCoords[counter] = *(points->GetTuple(i) + j);
++counter;
return 0;
}
}
std::vector<std::size_t> gmshTags(numTuples);
std::iota(gmshTags.begin(), gmshTags.end(), 1u);
gmsh::model::mesh::addNodes(
this->Internal->Dimension, this->Internal->ModelTag, gmshTags, inlineCoords);
}
//-----------------------------------------------------------------------------
void vtkGmshWriter::LoadCells()
{
vtkUnstructuredGrid* input = this->Internal->Input;
for (vtkIdType i = 0; i < numberOfCells; ++i)
{
const int vtkCellType = input->GetCellType(i);
// Build list of gmsh indexes per type
vtkCellArray* cells = input->GetCells();
vtkUnsignedCharArray* cellType = input->GetCellTypesArray();
std::vector<std::size_t> indexesPerTypes[GmshWriterInternal::MAX_TAG];
if (vtkCellType >= 15)
{
continue;
}
const int vtkTopologicalDim = ::TRANSLATE_CELLS_TYPE[vtkCellType].second;
if (vtkTopologicalDim < 0)
{
continue;
}
else if (vtkTopologicalDim != desiredDimension)
{
vtkGenericWarningMacro("Dropping " << name << ", cells of different dimension are found.");
return -1;
}
for (vtkIdType i = 0; i < cells->GetNumberOfCells(); ++i)
{
const unsigned char vtkCellType = cellType->GetValue(i);
if (!GmshWriterInternal::TRANSLATE_CELLS_TYPE.count(vtkCellType))
{
continue;
vtkCellIdxsPerType[vtkCellType].push_back(i);
}
indexesPerTypes[vtkCellType].push_back(i + 1);
}
// Add these cells to gmsh::model
::FillCells(this->Internal->ModelTag, this->Internal, indexesPerTypes, input,
cells->GetOffsetsArray(), cells->GetConnectivityArray());
}
//-----------------------------------------------------------------------------
void vtkGmshWriter::LoadNodeData()
{
vtkDataSetAttributes* pointData =
vtkDataSetAttributes::SafeDownCast(this->Internal->Input->GetPointData());
const int numVtkArrays = this->Internal->NodeViews.size();
if (numVtkArrays == 0)
// ========================================================
// Define physical group and its entity
const int currentEntity = gmsh::model::addDiscreteEntity(desiredDimension);
gmsh::model::addPhysicalGroup(desiredDimension, {currentEntity});
// TODO add its name
MPhysicalGroup currentGroup;
currentGroup.Dimension = desiredDimension;
currentGroup.Name = name;
currentGroup.Entity = currentEntity;
currentGroup.Grid = input;
currentGroup.CellOffset = this->Internal->CellOffsetSum;
currentGroup.NodeOffset = this->Internal->NodeOffsetSum;
this->Internal->PhysicalGroups.push_back(currentGroup);
// ==================== Load Nodes ========================
{
return;
}
const vtkIdType numTuples =
pointData->GetAbstractArray(pointData->GetArrayName(0))->GetNumberOfTuples();
// Generate Gmsh tags
std::vector<std::size_t> tags(numTuples);
std::iota(tags.begin(), tags.end(), 1);
vtkDataArray* points = input->GetPoints()->GetData();
for (int arrayId = 0; arrayId < numVtkArrays; ++arrayId)
{
// Get VTK data (we can safely safedowncast because we already checked in InitViews())
const std::string arrayName = this->Internal->NodeViews[arrayId];
vtkDataArray* vtkArray =
vtkDataArray::SafeDownCast(pointData->GetAbstractArray(arrayName.c_str()));
const int numComponents = vtkArray->GetNumberOfComponents();
// Store it in a structure Gmsh can understand
std::vector<double> gmshData(numTuples * numComponents);
gmshData.resize(numTuples * numComponents);
vtkIdType counter = 0;
for (vtkIdType i = 0; i < numTuples; ++i)
const vtkIdType numTuples = points->GetNumberOfTuples();
const vtkIdType numCompnt = points->GetNumberOfComponents();
std::vector<double> inlineCoords(numTuples * numCompnt);
// Store point coordinates in a structure Gmsh can understand
for (vtkIdType i = 0, counter = 0; i < numTuples; ++i)
{
for (int j = 0; j < numComponents; ++j)
for (vtkIdType j = 0; j < numCompnt; ++j)
{
gmshData[counter] = *(vtkArray->GetTuple(i) + j);
inlineCoords[counter] = *(points->GetTuple(i) + j);
++counter;
}
}
// Finally add it to gmsh
gmsh::view::addHomogeneousModelData(arrayId, this->Internal->CurrentTimeStep,
this->Internal->ModelName, "NodeData", tags, gmshData, this->Internal->CurrentTime,
numComponents);
}
}
std::vector<std::size_t> gmshNodeTags(numTuples);
std::iota(gmshNodeTags.begin(), gmshNodeTags.end(), currentGroup.NodeOffset);
this->Internal->NodeOffsetSum += numTuples;
//-----------------------------------------------------------------------------
void vtkGmshWriter::LoadCellData()
{
vtkDataSetAttributes* cellData =
vtkDataSetAttributes::SafeDownCast(this->Internal->Input->GetCellData());
const int numVtkArrays = this->Internal->CellViews.size();
if (numVtkArrays == 0)
{
return;
gmsh::model::mesh::addNodes(
desiredDimension, currentEntity, gmshNodeTags, inlineCoords);
}
// ========================================================
const int vtkArrayOffset = this->Internal->NodeViews.size();
// Generate Gmsh tags
std::vector<std::size_t> tags(this->Internal->CellDataIndex.size());
std::iota(tags.begin(), tags.end(), 1);
// Actually load cells
const vtkIdType numCells = ::FillCells(currentGroup, vtkCellIdxsPerType);
this->Internal->CellOffsetSum += numCells;
for (int arrayId = 0; arrayId < numVtkArrays; ++arrayId)
{
// Get VTK data (we can safely safedowncast because we already checked in InitViews())
std::string arrayName = this->Internal->CellViews[arrayId];
vtkDataArray* vtkArray =
vtkDataArray::SafeDownCast(cellData->GetAbstractArray(arrayName.c_str()));
const int numComponents = vtkArray->GetNumberOfComponents();
// Store it in a structure Gmsh can understand
std::vector<double> gmshData(this->Internal->CellDataIndex.size() * numComponents);
vtkIdType counter = 0;
for (std::size_t idx : this->Internal->CellDataIndex)
{
for (int j = 0; j < numComponents; ++j)
{
gmshData[counter] = *(vtkArray->GetTuple(idx) + j);
++counter;
}
}
// Finally add it to gmsh
gmsh::view::addHomogeneousModelData(arrayId + vtkArrayOffset, this->Internal->CurrentTimeStep,
this->Internal->ModelName, "ElementData", tags, gmshData, this->Internal->CurrentTime,
numComponents);
}
return 1;
}
//-----------------------------------------------------------------------------
......@@ -405,56 +372,10 @@ int vtkGmshWriter::RequestUpdateExtent(
return 1;
}
//-----------------------------------------------------------------------------
void vtkGmshWriter::InitViews()
{
vtkDataSetAttributes* pointsData =
vtkDataSetAttributes::SafeDownCast(this->Internal->Input->GetPointData());
int arrayCounter = 0;
std::string name;
const int nbPointArrays = pointsData->GetNumberOfArrays();
for (int i = 0; i < nbPointArrays; ++i)
{
name = pointsData->GetArrayName(i);
if (name.rfind("gmsh", 0) == 0 && !this->WriteGmshSpecificArray)
{
continue;
}
vtkDataArray* vtkArray = vtkDataArray::SafeDownCast(pointsData->GetAbstractArray(name.c_str()));
if (!vtkArray)
{
continue;
}
this->Internal->NodeViews.push_back(name);
gmsh::view::add(name, arrayCounter);
++arrayCounter;
}
vtkDataSetAttributes* cellsData =
vtkDataSetAttributes::SafeDownCast(this->Internal->Input->GetCellData());
const int nbCellArrays = cellsData->GetNumberOfArrays();
for (int i = 0; i < nbCellArrays; ++i)
{
name = cellsData->GetArrayName(i);
if (name.rfind("gmsh", 0) == 0 && !this->WriteGmshSpecificArray)
{
continue;
}
vtkDataArray* vtkArray = vtkDataArray::SafeDownCast(cellsData->GetAbstractArray(name.c_str()));
if (!vtkArray)
{
continue;
}
this->Internal->CellViews.push_back(name);
gmsh::view::add(name, arrayCounter);
++arrayCounter;
}
}
//-----------------------------------------------------------------------------
int vtkGmshWriter::RequestData(
vtkInformation* request, vtkInformationVector**, vtkInformationVector*)
vtkInformation* request, vtkInformationVector** inputVector, vtkInformationVector*)
{
// make sure the user specified a FileName
if (!this->FileName)
......@@ -463,53 +384,74 @@ int vtkGmshWriter::RequestData(
return 0;
}
this->Internal->Input = this->GetInput();
vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
this->OriginalInput = vtkDataObject::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
// If this is the first request
if (this->Internal->CurrentTimeStep == 0)
// if (this->Internal->CurrentTimeStep == 0)
{
std::string file(this->FileName);
gmsh::initialize();
gmsh::option::setNumber("General.Verbosity", 1);
gmsh::option::setNumber("PostProcessing.SaveMesh", 0);
gmsh::model::add(this->Internal->ModelName.c_str());
gmsh::model::addDiscreteEntity(0);
gmsh::model::addDiscreteEntity(1);
gmsh::model::addDiscreteEntity(2);
gmsh::model::addDiscreteEntity(3);
this->Internal->Dimension = 3;
// Get tag of the current model
switch (this->OriginalInput->GetDataObjectType())
{
gmsh::vectorpair tmp;
gmsh::model::getEntities(tmp);
this->Internal->ModelTag = tmp[0].second;
case VTK_UNSTRUCTURED_GRID:
{
vtkUnstructuredGrid* input = vtkUnstructuredGrid::SafeDownCast(this->OriginalInput);
std::cout << "Writing unstructured grid" << std::endl;
// LoadGridIntoPhysicalGroup(input, "");
break;
}
case VTK_MULTIBLOCK_DATA_SET:
{
std::cout << "Multiblock dataset" << std::endl;
vtkMultiBlockDataSet* compositeData = vtkMultiBlockDataSet::SafeDownCast(this->OriginalInput);
vtkCompositeDataIterator* iter = compositeData->NewIterator();
for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
{
vtkUnstructuredGrid* leaf = vtkUnstructuredGrid::SafeDownCast(iter->GetCurrentDataObject());
const char* blockName = compositeData->GetMetaData(iter)->Get(vtkCompositeDataSet::NAME());
if (leaf == nullptr)
{
vtkWarningMacro("Leaf " << blockName << " is not an unstructured grid.");
break;
}
const int vtkType = leaf->GetCellType(0);
int dimension = -1;
if (vtkType < ::MAX_TYPE)
{
dimension = ::TRANSLATE_CELLS_TYPE[vtkType].second;
}
if (dimension < 0)
{
vtkWarningMacro("Leaf " << blockName << " contains unsupported data type.");
break;
}
std::cout << "writing physical group " << blockName << "of dimension " << dimension << std::endl