VTK-m  2.2
VTKDataSetCells.h
Go to the documentation of this file.
1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10 #ifndef vtk_m_io_internal_VTKDataSetCells_h
11 #define vtk_m_io_internal_VTKDataSetCells_h
12 
13 #include <vtkm/CellShape.h>
14 #include <vtkm/Types.h>
15 #include <vtkm/cont/ArrayHandle.h>
17 #include <vtkm/io/ErrorIO.h>
18 
19 #include <algorithm>
20 #include <vector>
21 
22 namespace vtkm
23 {
24 namespace io
25 {
26 namespace internal
27 {
28 
29 enum UnsupportedVTKCells
30 {
31  CELL_SHAPE_POLY_VERTEX = 2,
33  CELL_SHAPE_TRIANGLE_STRIP = 6,
34  CELL_SHAPE_PIXEL = 8,
35  CELL_SHAPE_VOXEL = 11
36 };
37 
38 inline void FixupCellSet(vtkm::cont::ArrayHandle<vtkm::Id>& connectivity,
42 {
43  std::vector<vtkm::Id> newConnectivity;
44  std::vector<vtkm::IdComponent> newNumIndices;
45  std::vector<vtkm::UInt8> newShapes;
46  std::vector<vtkm::Id> permutationVec;
47 
48  vtkm::Id connIdx = 0;
49  auto shapesPortal = shapes.ReadPortal();
50  auto indicesPortal = numIndices.ReadPortal();
51  auto connPortal = connectivity.ReadPortal();
52  for (vtkm::Id i = 0; i < shapes.GetNumberOfValues(); ++i)
53  {
54  vtkm::UInt8 shape = shapesPortal.Get(i);
55  vtkm::IdComponent numInds = indicesPortal.Get(i);
56  switch (shape)
57  {
66  {
67  newShapes.push_back(shape);
68  newNumIndices.push_back(numInds);
69  for (vtkm::IdComponent j = 0; j < numInds; ++j)
70  {
71  newConnectivity.push_back(connPortal.Get(connIdx++));
72  }
73  permutationVec.push_back(i);
74  break;
75  }
77  {
78  vtkm::IdComponent numVerts = numInds;
80  if (numVerts == 3)
81  {
82  newShape = vtkm::CELL_SHAPE_TRIANGLE;
83  }
84  else if (numVerts == 4)
85  {
86  newShape = vtkm::CELL_SHAPE_QUAD;
87  }
88  newShapes.push_back(newShape);
89  newNumIndices.push_back(numVerts);
90  for (vtkm::IdComponent j = 0; j < numVerts; ++j)
91  {
92  newConnectivity.push_back(connPortal.Get(connIdx++));
93  }
94  permutationVec.push_back(i);
95  break;
96  }
97  case CELL_SHAPE_POLY_VERTEX:
98  {
99  vtkm::IdComponent numVerts = numInds;
100  for (vtkm::IdComponent j = 0; j < numVerts; ++j)
101  {
102  newShapes.push_back(vtkm::CELL_SHAPE_VERTEX);
103  newNumIndices.push_back(1);
104  newConnectivity.push_back(connPortal.Get(connIdx));
105  permutationVec.push_back(i);
106  ++connIdx;
107  }
108  break;
109  }
111  {
112  vtkm::IdComponent numLines = numInds - 1;
113  for (vtkm::IdComponent j = 0; j < numLines; ++j)
114  {
115  newShapes.push_back(vtkm::CELL_SHAPE_LINE);
116  newNumIndices.push_back(2);
117  newConnectivity.push_back(connPortal.Get(connIdx));
118  newConnectivity.push_back(connPortal.Get(connIdx + 1));
119  permutationVec.push_back(i);
120  ++connIdx;
121  }
122  connIdx += 1;
123  break;
124  }
125  case CELL_SHAPE_TRIANGLE_STRIP:
126  {
127  vtkm::IdComponent numTris = numInds - 2;
128  for (vtkm::IdComponent j = 0; j < numTris; ++j)
129  {
130  newShapes.push_back(vtkm::CELL_SHAPE_TRIANGLE);
131  newNumIndices.push_back(3);
132  if (j % 2)
133  {
134  newConnectivity.push_back(connPortal.Get(connIdx));
135  newConnectivity.push_back(connPortal.Get(connIdx + 1));
136  newConnectivity.push_back(connPortal.Get(connIdx + 2));
137  }
138  else
139  {
140  newConnectivity.push_back(connPortal.Get(connIdx + 2));
141  newConnectivity.push_back(connPortal.Get(connIdx + 1));
142  newConnectivity.push_back(connPortal.Get(connIdx));
143  }
144  permutationVec.push_back(i);
145  ++connIdx;
146  }
147  connIdx += 2;
148  break;
149  }
150  case CELL_SHAPE_PIXEL:
151  {
152  newShapes.push_back(vtkm::CELL_SHAPE_QUAD);
153  newNumIndices.push_back(numInds);
154  newConnectivity.push_back(connPortal.Get(connIdx + 0));
155  newConnectivity.push_back(connPortal.Get(connIdx + 1));
156  newConnectivity.push_back(connPortal.Get(connIdx + 3));
157  newConnectivity.push_back(connPortal.Get(connIdx + 2));
158  permutationVec.push_back(i);
159  connIdx += 4;
160  break;
161  }
162  case CELL_SHAPE_VOXEL:
163  {
164  newShapes.push_back(vtkm::CELL_SHAPE_HEXAHEDRON);
165  newNumIndices.push_back(numInds);
166  newConnectivity.push_back(connPortal.Get(connIdx + 0));
167  newConnectivity.push_back(connPortal.Get(connIdx + 1));
168  newConnectivity.push_back(connPortal.Get(connIdx + 3));
169  newConnectivity.push_back(connPortal.Get(connIdx + 2));
170  newConnectivity.push_back(connPortal.Get(connIdx + 4));
171  newConnectivity.push_back(connPortal.Get(connIdx + 5));
172  newConnectivity.push_back(connPortal.Get(connIdx + 7));
173  newConnectivity.push_back(connPortal.Get(connIdx + 6));
174  permutationVec.push_back(i);
175  connIdx += 8;
176  break;
177  }
178  default:
179  {
180  throw vtkm::io::ErrorIO("Encountered unsupported cell type");
181  }
182  }
183  }
184 
185  if (newShapes.size() == static_cast<std::size_t>(shapes.GetNumberOfValues()))
186  {
187  permutationVec.clear();
188  }
189  else
190  {
191  permutation.Allocate(static_cast<vtkm::Id>(permutationVec.size()));
192  std::copy(permutationVec.begin(),
193  permutationVec.end(),
195  }
196 
197  shapes.Allocate(static_cast<vtkm::Id>(newShapes.size()));
198  std::copy(newShapes.begin(),
199  newShapes.end(),
201  numIndices.Allocate(static_cast<vtkm::Id>(newNumIndices.size()));
202  std::copy(newNumIndices.begin(),
203  newNumIndices.end(),
205  connectivity.Allocate(static_cast<vtkm::Id>(newConnectivity.size()));
206  std::copy(newConnectivity.begin(),
207  newConnectivity.end(),
209 }
210 
211 inline bool IsSingleShape(const vtkm::cont::ArrayHandle<vtkm::UInt8>& shapes)
212 {
213  if (shapes.GetNumberOfValues() < 1)
214  {
215  // If the data has no cells, is it single shape? That would make sense, but having
216  // a single shape cell set requires you to slect a shape, and there are no cells to
217  // make that selection from. We could get around that, but it's easier just to treat
218  // it as a general explicit grid.
219  return false;
220  }
221 
222  auto shapesPortal = shapes.ReadPortal();
223  vtkm::UInt8 shape0 = shapesPortal.Get(0);
224  for (vtkm::Id i = 1; i < shapes.GetNumberOfValues(); ++i)
225  {
226  if (shapesPortal.Get(i) != shape0)
227  return false;
228  }
229 
230  return true;
231 }
232 }
233 }
234 } // vtkm::io::internal
235 
236 #endif // vtk_m_io_internal_VTKDataSetCells_h
vtkm::cont::ArrayHandle< vtkm::Id >
ArrayHandle.h
vtkm::CELL_SHAPE_WEDGE
@ CELL_SHAPE_WEDGE
A wedge.
Definition: CellShape.h:66
vtkm
Groups connected points that have the same field value.
Definition: Atomic.h:19
Types.h
vtkm::IdComponent
vtkm::Int32 IdComponent
Base type to use to index small lists.
Definition: Types.h:194
ArrayPortalToIterators.h
vtkm::cont::ArrayHandle::GetNumberOfValues
vtkm::Id GetNumberOfValues() const
Returns the number of entries in the array.
Definition: ArrayHandle.h:468
CellShape.h
vtkm::CELL_SHAPE_POLY_LINE
@ CELL_SHAPE_POLY_LINE
A sequence of line segments.
Definition: CellShape.h:46
vtkm::io::ErrorIO
This class is thrown when VTK-m encounters an error with the file system.
Definition: ErrorIO.h:25
vtkm::CELL_SHAPE_TETRA
@ CELL_SHAPE_TETRA
A tetrahedron.
Definition: CellShape.h:59
ErrorIO.h
vtkm::Id
vtkm::Int64 Id
Base type to use to index arrays.
Definition: Types.h:227
vtkm::CELL_SHAPE_HEXAHEDRON
@ CELL_SHAPE_HEXAHEDRON
A hexahedron.
Definition: CellShape.h:62
vtkm::UInt8
uint8_t UInt8
Base type to use for 8-bit unsigned integer numbers.
Definition: Types.h:169
vtkm::CELL_SHAPE_TRIANGLE
@ CELL_SHAPE_TRIANGLE
A triangle.
Definition: CellShape.h:48
vtkm::CELL_SHAPE_LINE
@ CELL_SHAPE_LINE
A line cell connecting two points.
Definition: CellShape.h:42
vtkm::cont::ArrayHandle::ReadPortal
ReadPortalType ReadPortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:433
vtkm::cont::ArrayPortalToIteratorBegin
vtkm::cont::ArrayPortalToIterators< PortalType >::IteratorType ArrayPortalToIteratorBegin(const PortalType &portal)
Convenience function for converting an ArrayPortal to a begin iterator.
Definition: ArrayPortalToIterators.h:178
vtkm::cont::ArrayHandle::Allocate
void Allocate(vtkm::Id numberOfValues, vtkm::CopyFlag preserve, vtkm::cont::Token &token) const
Allocates an array large enough to hold the given number of values.
Definition: ArrayHandle.h:490
vtkm::CELL_SHAPE_PYRAMID
@ CELL_SHAPE_PYRAMID
A pyramid with a quadrilateral base and four triangular faces.0.
Definition: CellShape.h:68
vtkm::cont::ArrayHandle::WritePortal
WritePortalType WritePortal() const
Get an array portal that can be used in the control environment.
Definition: ArrayHandle.h:454
vtkm::CELL_SHAPE_POLYGON
@ CELL_SHAPE_POLYGON
A general polygon shape.
Definition: CellShape.h:53
vtkm::CELL_SHAPE_VERTEX
@ CELL_SHAPE_VERTEX
Vertex cells of a single point.
Definition: CellShape.h:39
vtkm::CELL_SHAPE_QUAD
@ CELL_SHAPE_QUAD
A four-sided polygon.
Definition: CellShape.h:56