vtk-m/vtkm/io/internal/VTKDataSetCells.h
2015-11-24 13:56:23 -05:00

235 lines
7.6 KiB
C++

//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt 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 2015 Sandia Corporation.
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_io_internal_VTKDataSetCells_h
#define vtk_m_io_internal_VTKDataSetCells_h
#include <vtkm/CellShape.h>
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/io/ErrorIO.h>
#include <algorithm>
#include <vector>
namespace vtkm {
namespace io {
namespace internal {
enum UnsupportedVTKCells
{
CELL_SHAPE_POLY_VERTEX = 2,
CELL_SHAPE_POLY_LINE = 4,
CELL_SHAPE_TRIANGLE_STRIP = 6,
CELL_SHAPE_PIXEL = 8,
CELL_SHAPE_VOXEL = 11
};
inline void FixupCellSet(vtkm::cont::ArrayHandle<vtkm::Id> &connectivity,
vtkm::cont::ArrayHandle<vtkm::IdComponent> &numIndices,
vtkm::cont::ArrayHandle<vtkm::UInt8> &shapes,
vtkm::cont::ArrayHandle<vtkm::Id> &permutation)
{
std::vector<vtkm::Id> newConnectivity;
std::vector<vtkm::IdComponent> newNumIndices;
std::vector<vtkm::UInt8> newShapes;
std::vector<vtkm::Id> permutationVec;
vtkm::Id connIdx = 0;
for (vtkm::Id i = 0; i < shapes.GetNumberOfValues(); ++i)
{
vtkm::UInt8 shape = shapes.GetPortalConstControl().Get(i);
vtkm::IdComponent numInds = numIndices.GetPortalConstControl().Get(i);
vtkm::cont::ArrayHandle<vtkm::Id>::PortalConstControl connPortal =
connectivity.GetPortalConstControl();
switch (shape)
{
case vtkm::CELL_SHAPE_VERTEX:
case vtkm::CELL_SHAPE_LINE:
case vtkm::CELL_SHAPE_TRIANGLE:
case vtkm::CELL_SHAPE_QUAD:
case vtkm::CELL_SHAPE_TETRA:
case vtkm::CELL_SHAPE_HEXAHEDRON:
case vtkm::CELL_SHAPE_WEDGE:
case vtkm::CELL_SHAPE_PYRAMID:
{
newShapes.push_back(shape);
newNumIndices.push_back(numInds);
for (vtkm::IdComponent j = 0; j < numInds; ++j)
{
newConnectivity.push_back(connPortal.Get(connIdx++));
}
permutationVec.push_back(i);
break;
}
case vtkm::CELL_SHAPE_POLYGON:
{
vtkm::IdComponent numVerts = numInds;
vtkm::UInt8 newShape = vtkm::CELL_SHAPE_POLYGON;
if (numVerts == 3)
{
newShape = vtkm::CELL_SHAPE_TRIANGLE;
}
else if (numVerts == 4)
{
newShape = vtkm::CELL_SHAPE_QUAD;
}
newShapes.push_back(newShape);
newNumIndices.push_back(numVerts);
for (vtkm::IdComponent j = 0; j < numVerts; ++j)
{
newConnectivity.push_back(connPortal.Get(connIdx++));
}
permutationVec.push_back(i);
break;
}
case CELL_SHAPE_POLY_VERTEX:
{
vtkm::IdComponent numVerts = numInds;
for (vtkm::IdComponent j = 0; j < numVerts; ++j)
{
newShapes.push_back(vtkm::CELL_SHAPE_VERTEX);
newNumIndices.push_back(1);
newConnectivity.push_back(connPortal.Get(connIdx));
permutationVec.push_back(i);
++connIdx;
}
break;
}
case CELL_SHAPE_POLY_LINE:
{
vtkm::IdComponent numLines = numInds - 1;
for (vtkm::IdComponent j = 0; j < numLines; ++j)
{
newShapes.push_back(vtkm::CELL_SHAPE_LINE);
newNumIndices.push_back(2);
newConnectivity.push_back(connPortal.Get(connIdx));
newConnectivity.push_back(connPortal.Get(connIdx+1));
permutationVec.push_back(i);
++connIdx;
}
connIdx += 1;
break;
}
case CELL_SHAPE_TRIANGLE_STRIP:
{
vtkm::IdComponent numTris = numInds - 2;
for (vtkm::IdComponent j = 0; j < numTris; ++j)
{
newShapes.push_back(vtkm::CELL_SHAPE_TRIANGLE);
newNumIndices.push_back(3);
if (j % 2)
{
newConnectivity.push_back(connPortal.Get(connIdx));
newConnectivity.push_back(connPortal.Get(connIdx+1));
newConnectivity.push_back(connPortal.Get(connIdx+2));
}
else
{
newConnectivity.push_back(connPortal.Get(connIdx+2));
newConnectivity.push_back(connPortal.Get(connIdx+1));
newConnectivity.push_back(connPortal.Get(connIdx));
}
permutationVec.push_back(i);
++connIdx;
}
connIdx += 2;
break;
}
case CELL_SHAPE_PIXEL:
{
newShapes.push_back(vtkm::CELL_SHAPE_QUAD);
newNumIndices.push_back(numInds);
newConnectivity.push_back(connPortal.Get(connIdx + 0));
newConnectivity.push_back(connPortal.Get(connIdx + 1));
newConnectivity.push_back(connPortal.Get(connIdx + 3));
newConnectivity.push_back(connPortal.Get(connIdx + 2));
permutationVec.push_back(i);
connIdx += 4;
break;
}
case CELL_SHAPE_VOXEL:
{
newShapes.push_back(vtkm::CELL_SHAPE_HEXAHEDRON);
newNumIndices.push_back(numInds);
newConnectivity.push_back(connPortal.Get(connIdx + 0));
newConnectivity.push_back(connPortal.Get(connIdx + 1));
newConnectivity.push_back(connPortal.Get(connIdx + 3));
newConnectivity.push_back(connPortal.Get(connIdx + 2));
newConnectivity.push_back(connPortal.Get(connIdx + 4));
newConnectivity.push_back(connPortal.Get(connIdx + 5));
newConnectivity.push_back(connPortal.Get(connIdx + 7));
newConnectivity.push_back(connPortal.Get(connIdx + 6));
permutationVec.push_back(i);
connIdx += 6;
break;
}
default:
{
throw vtkm::io::ErrorIO("Encountered unsupported cell type");
}
}
}
if (newShapes.size() == static_cast<std::size_t>(shapes.GetNumberOfValues()))
{
permutationVec.clear();
}
else
{
permutation.Allocate(static_cast<vtkm::Id>(permutationVec.size()));
std::copy(permutationVec.begin(), permutationVec.end(),
vtkm::cont::ArrayPortalToIteratorBegin(permutation.GetPortalControl()));
}
shapes.Allocate(static_cast<vtkm::Id>(newShapes.size()));
std::copy(newShapes.begin(), newShapes.end(),
vtkm::cont::ArrayPortalToIteratorBegin(shapes.GetPortalControl()));
numIndices.Allocate(static_cast<vtkm::Id>(newNumIndices.size()));
std::copy(newNumIndices.begin(), newNumIndices.end(),
vtkm::cont::ArrayPortalToIteratorBegin(numIndices.GetPortalControl()));
connectivity.Allocate(static_cast<vtkm::Id>(newConnectivity.size()));
std::copy(newConnectivity.begin(), newConnectivity.end(),
vtkm::cont::ArrayPortalToIteratorBegin(connectivity.GetPortalControl()));
}
inline bool IsSingleShape(const vtkm::cont::ArrayHandle<vtkm::UInt8> &shapes)
{
vtkm::cont::ArrayHandle<vtkm::UInt8>::PortalConstControl shapesPortal =
shapes.GetPortalConstControl();
vtkm::UInt8 shape0 = shapesPortal.Get(0);
for (vtkm::Id i = 1; i < shapes.GetNumberOfValues(); ++i)
{
if (shapesPortal.Get(i) != shape0)
return false;
}
return true;
}
}
}
} // vtkm::io::internal
#endif // vtk_m_io_internal_VTKDataSetCells_h