1 /*=========================================================================
2
3 Program: Visualization Toolkit
4 Module: vtkStructuredData.h
5
6 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 All rights reserved.
8 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9
10 This software is distributed WITHOUT ANY WARRANTY; without even
11 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12 PURPOSE. See the above copyright notice for more information.
13
14 =========================================================================*/
15 /**
16 * @class vtkStructuredData
17 * @brief Singleton class for topologically regular data
18 *
19 *
20 * vtkStructuredData is a singleton class that provides an interface for
21 * topologically regular data. Regular data is data that can be accessed
22 * in rectangular fashion using an i-j-k index. A finite difference grid,
23 * a volume, or a pixmap are all considered regular.
24 *
25 * @sa
26 * vtkStructuredGrid vtkUniformGrid vtkRectilinearGrid vtkRectilinearGrid
27 */
28
29 #ifndef vtkStructuredData_h
30 #define vtkStructuredData_h
31
32 #include "vtkCommonDataModelModule.h" // For export macro
33 #include "vtkObject.h"
34
35 class vtkIdList;
36
37 #define VTK_UNCHANGED 0
38 #define VTK_SINGLE_POINT 1
39 #define VTK_X_LINE 2
40 #define VTK_Y_LINE 3
41 #define VTK_Z_LINE 4
42 #define VTK_XY_PLANE 5
43 #define VTK_YZ_PLANE 6
44 #define VTK_XZ_PLANE 7
45 #define VTK_XYZ_GRID 8
46 #define VTK_EMPTY 9
47
48 class VTKCOMMONDATAMODEL_EXPORT vtkStructuredData : public vtkObject
49 {
50 public:
51 vtkTypeMacro(vtkStructuredData,vtkObject);
52
53 //@{
54 /**
55 * Specify the dimensions of a regular, rectangular dataset. The input is
56 * the new dimensions (inDim) and the current dimensions (dim). The function
57 * returns the dimension of the dataset (0-3D). If the dimensions are
58 * improperly specified a -1 is returned. If the dimensions are unchanged, a
59 * value of 100 is returned.
60 */
61 static int SetDimensions(int inDim[3], int dim[3]);
62 static int SetExtent(int inExt[6], int ext[6]);
63 //@}
64
65 //@{
66 /**
67 * Returns the data description given the dimensions (eg. VTK_SINGLE_POINT,
68 * VTK_X_LINE, VTK_XY_PLANE etc.)
69 */
70 static int GetDataDescription(int dims[3]);
71 static int GetDataDescriptionFromExtent( int ext[6] );
72 //@}
73
74 //@{
75 /**
76 * Return the topological dimension of the data (e.g., 0, 1, 2, or 3D).
77 */
78 static int GetDataDimension(int dataDescription);
79 static int GetDataDimension( int ext[6] );
80 //@}
81
82 /**
83 * Given the grid extent, this method returns the total number of points
84 * within the extent.
85 * The dataDescription field is not used.
86 */
87 static vtkIdType GetNumberOfPoints(int ext[6], int dataDescription=VTK_EMPTY);
88
89 /**
90 * Given the grid extent, this method returns the total number of cells
91 * within the extent.
92 * The dataDescription field is not used.
93 */
94 static vtkIdType GetNumberOfCells(int ext[6], int dataDescription=VTK_EMPTY);
95
96 /**
97 * Given the point extent of a grid, this method computes the corresponding
98 * cell extent for the grid.
99 * The dataDescription field is not used.
100 */
101 static void GetCellExtentFromPointExtent(
102 int pntExtent[6], int cellExtent[6], int dataDescription=VTK_EMPTY );
103
104 /**
105 * Computes the structured grid dimensions based on the given extent.
106 * The dataDescription field is not used.
107 */
108 static void GetDimensionsFromExtent(
109 int ext[6], int dims[3], int dataDescription=VTK_EMPTY );
110
111 /**
112 * Returns the cell dimensions, i.e., the number of cells along the i,j,k
113 * for the grid with the given grid extent. Note, the grid extent is the
114 * number of points.
115 * The dataDescription field is not used.
116 */
117 static void GetCellDimensionsFromExtent(
118 int ext[6], int celldims[3], int dataDescription=VTK_EMPTY );
119
120 /**
121 * Given the dimensions of the grid, in pntdims, this method returns
122 * the corresponding cell dimensions for the given grid.
123 * The dataDescription field is not used.
124 */
125 static void GetCellDimensionsFromPointDimensions(
126 int pntdims[3],int cellDims[3] );
127
128 /**
129 * Given the global structured coordinates for a point or cell, ijk, w.r.t.
130 * as well as, the global sub-grid cell or point extent, this method computes
131 * the corresponding local structured coordinates, lijk, starting from 0.
132 * The dataDescription argument is not used.
133 */
134 static void GetLocalStructuredCoordinates(
135 int ijk[3], int ext[6], int lijk[3], int dataDescription=VTK_EMPTY );
136
137 /**
138 * Given local structured coordinates, and the corresponding global sub-grid
139 * extent, this method computes the global ijk coordinates.
140 * The dataDescription parameter is not used.
141 */
142 static void GetGlobalStructuredCoordinates(
143 int lijk[3], int ext[6], int ijk[3], int dataDescription=VTK_EMPTY );
144
145 /**
146 * Get the points defining a cell. (See vtkDataSet for more info.)
147 */
148 static void GetCellPoints(vtkIdType cellId, vtkIdList *ptIds,
149 int dataDescription, int dim[3]);
150
151 /**
152 * Get the cells using a point. (See vtkDataSet for more info.)
153 */
154 static void GetPointCells(vtkIdType ptId, vtkIdList *cellIds, int dim[3]);
155
156 /**
157 * Get the cells using the points ptIds, exclusive of the cell cellId.
158 * (See vtkDataSet for more info.)
159 */
160 static void GetCellNeighbors(vtkIdType cellId, vtkIdList *ptIds,
161 vtkIdList *cellIds, int dim[3]);
162 static void GetCellNeighbors(vtkIdType cellId, vtkIdList *ptIds,
163 vtkIdList *cellIds, int dim[3], int seedLoc[3]);
164
165 /**
166 * Given a location in structured coordinates (i-j-k), and the extent
167 * of the structured dataset, return the point id.
168 * The dataDescription argument is not used.
169 */
170 static vtkIdType ComputePointIdForExtent(int extent[6], int ijk[3],
171 int dataDescription=VTK_EMPTY );
172
173 /**
174 * Given a location in structured coordinates (i-j-k), and the extent
175 * of the structured dataset, return the point id.
176 * The dataDescription argument is not used.
177 */
178 static vtkIdType ComputeCellIdForExtent(
179 int extent[6], int ijk[3], int dataDescription=VTK_EMPTY );
180
181 /**
182 * Given a location in structured coordinates (i-j-k), and the dimensions
183 * of the structured dataset, return the point id. This method does not
184 * adjust for the beginning of the extent.
185 * The dataDescription argument is not used.
186 */
187 static vtkIdType ComputePointId(
188 int dim[3], int ijk[3], int dataDescription=VTK_EMPTY );
189
190 /**
191 * Given a location in structured coordinates (i-j-k), and the dimensions
192 * of the structured dataset, return the cell id. This method does not
193 * adjust for the beginning of the extent.
194 * The dataDescription argument is not used.
195 */
196 static vtkIdType ComputeCellId(
197 int dim[3], int ijk[3], int dataDescription=VTK_EMPTY );
198
199 /**
200 * Given the global grid extent and the linear index of a cell within the
201 * grid extent, this method computes the corresponding structured coordinates
202 * of the given cell. This method adjusts for the beginning of the extent.
203 * The dataDescription argument is not used.
204 */
205 static void ComputeCellStructuredCoordsForExtent(
206 const vtkIdType cellIdx, int ext[6], int ijk[3],
207 int dataDescription=VTK_EMPTY );
208
209 /**
210 * Given a cellId and grid dimensions 'dim', get the structured coordinates
211 * (i-j-k). This method does not adjust for the beginning of the extent.
212 * The dataDescription argument is not used.
213 */
214 static void ComputeCellStructuredCoords(
215 const vtkIdType cellId, int dim[3], int ijk[3],
216 int dataDescription=VTK_EMPTY );
217
218 /**
219 * Given a pointId and the grid extent ext, get the structured coordinates
220 * (i-j-k). This method adjusts for the beginning of the extent.
221 * The dataDescription argument is not used.
222 */
223 static void ComputePointStructuredCoordsForExtent(
224 const vtkIdType ptId, int ext[6], int ijk[3],
225 int dataDescription=VTK_EMPTY );
226
227 /**
228 * Given a pointId and grid dimensions 'dim', get the structured coordinates
229 * (i-j-k). This method does not adjust for the beginning of the extent.
230 * The dataDescription argument is not used.
231 */
232 static void ComputePointStructuredCoords(
233 const vtkIdType ptId, int dim[3], int ijk[3],
234 int dataDescription=VTK_EMPTY );
235
236 protected:
vtkStructuredData()237 vtkStructuredData() {}
~vtkStructuredData()238 ~vtkStructuredData() override {}
239
240 /**
241 * Computes the linear index for the given i-j-k structured of a grid with
242 * of N1 and N2 dimensions along its principal directions. For example, the
243 * principal directions of a 3-D grid are Ni and Nj and likewise for a 2-D
244 * grid along the XY plane. For a grid in the XZ plane however, the principal
245 * directions are Ni and Nk.
246 */
GetLinearIndex(const int i,const int j,const int k,const int N1,const int N2)247 static vtkIdType GetLinearIndex(
248 const int i, const int j, const int k, const int N1, const int N2 )
249 {
250 return( (static_cast<vtkIdType>(k)*N2+j)*N1+i );
251 }
252
253 //@{
254 /**
255 * Returns the structured coordinates (i,j,k) for the given linear index of
256 * a grid with N1 and N2 dimensions along its principal directions.
257 * NOTE: i,j,k are relative to the frame of reference of the grid. For example,
258 * if the grid is on the XZ-Plane, then i=>i, j=>k, k=>j.
259 */
GetStructuredCoordinates(const vtkIdType idx,const int N1,const int N2,int & i,int & j,int & k)260 static void GetStructuredCoordinates(
261 const vtkIdType idx, const int N1, const int N2,int &i, int &j, int &k )
262 {
263 int N12 = N1*N2;
264 k = idx/N12;
265 j = (idx-k*N12)/N1;
266 i = idx-k*N12-j*N1;
267 }
268 //@}
269
270 // Want to avoid importing <algorithm> in the header...
271 template <typename T>
Max(const T & a,const T & b)272 static T Max(const T &a, const T &b)
273 {
274 return (a > b) ? a : b;
275 }
276
277 private:
278 vtkStructuredData(const vtkStructuredData&) = delete;
279 void operator=(const vtkStructuredData&) = delete;
280 };
281
282 //------------------------------------------------------------------------------
GetCellDimensionsFromExtent(int ext[6],int celldims[3],int)283 inline void vtkStructuredData::GetCellDimensionsFromExtent(
284 int ext[6], int celldims[3], int)
285 {
286 celldims[0] = vtkStructuredData::Max(ext[1] - ext[0], 0);
287 celldims[1] = vtkStructuredData::Max(ext[3] - ext[2], 0);
288 celldims[2] = vtkStructuredData::Max(ext[5] - ext[4], 0);
289 }
290
291 //------------------------------------------------------------------------------
ComputePointId(int dims[3],int ijk[3],int)292 inline vtkIdType vtkStructuredData::ComputePointId(int dims[3], int ijk[3], int)
293 {
294 return vtkStructuredData::GetLinearIndex(ijk[0], ijk[1], ijk[2],
295 dims[0], dims[1]);
296 }
297
298 //------------------------------------------------------------------------------
ComputeCellId(int dims[3],int ijk[3],int)299 inline vtkIdType vtkStructuredData::ComputeCellId(int dims[3], int ijk[3], int)
300 {
301 return vtkStructuredData::GetLinearIndex(
302 ijk[0], ijk[1], ijk[2],
303 vtkStructuredData::Max(dims[0] - 1, 1),
304 vtkStructuredData::Max(dims[1] - 1, 1));
305 }
306
307 //------------------------------------------------------------------------------
GetNumberOfPoints(int ext[6],int)308 inline vtkIdType vtkStructuredData::GetNumberOfPoints(int ext[6], int)
309 {
310 return static_cast<vtkIdType>(ext[1] - ext[0] + 1) *
311 static_cast<vtkIdType>(ext[3] - ext[2] + 1) *
312 static_cast<vtkIdType>(ext[5] - ext[4] + 1);
313 }
314
315 //------------------------------------------------------------------------------
GetNumberOfCells(int ext[6],int)316 inline vtkIdType vtkStructuredData::GetNumberOfCells(int ext[6], int)
317 {
318 int cellDims[3];
319 vtkStructuredData::GetCellDimensionsFromExtent(ext,cellDims);
320
321 // Replace 0's with 1's so we can just multiply them regardless of cell type.
322 cellDims[0] = vtkStructuredData::Max(cellDims[0], 1);
323 cellDims[1] = vtkStructuredData::Max(cellDims[1], 1);
324 cellDims[2] = vtkStructuredData::Max(cellDims[2], 1);
325
326 // Note, when we compute the result below, we statically cast to vtkIdType to
327 // ensure the compiler will generate a 32x32=64 instruction.
328 return static_cast<vtkIdType>(cellDims[0]) *
329 static_cast<vtkIdType>(cellDims[1]) *
330 static_cast<vtkIdType>(cellDims[2]);
331 }
332
333 //------------------------------------------------------------------------------
GetCellExtentFromPointExtent(int nodeExtent[6],int cellExtent[6],int)334 inline void vtkStructuredData::GetCellExtentFromPointExtent(
335 int nodeExtent[6], int cellExtent[6], int)
336 {
337 cellExtent[0] = nodeExtent[0];
338 cellExtent[2] = nodeExtent[2];
339 cellExtent[4] = nodeExtent[4];
340
341 cellExtent[1] = vtkStructuredData::Max(nodeExtent[0], nodeExtent[1] - 1);
342 cellExtent[3] = vtkStructuredData::Max(nodeExtent[2], nodeExtent[3] - 1);
343 cellExtent[5] = vtkStructuredData::Max(nodeExtent[4], nodeExtent[5] - 1);
344 }
345
346 //------------------------------------------------------------------------------
GetDimensionsFromExtent(int ext[6],int dims[3],int)347 inline void vtkStructuredData::GetDimensionsFromExtent(int ext[6], int dims[3],
348 int)
349 {
350 dims[0] = ext[1] - ext[0] + 1;
351 dims[1] = ext[3] - ext[2] + 1;
352 dims[2] = ext[5] - ext[4] + 1;
353 }
354
355 //------------------------------------------------------------------------------
GetCellDimensionsFromPointDimensions(int nodeDims[3],int cellDims[3])356 inline void vtkStructuredData::GetCellDimensionsFromPointDimensions(
357 int nodeDims[3], int cellDims[3])
358 {
359 cellDims[0] = vtkStructuredData::Max(nodeDims[0] - 1, 0);
360 cellDims[1] = vtkStructuredData::Max(nodeDims[1] - 1, 0);
361 cellDims[2] = vtkStructuredData::Max(nodeDims[2] - 1, 0);
362 }
363
364 //------------------------------------------------------------------------------
GetLocalStructuredCoordinates(int ijk[3],int ext[6],int lijk[3],int)365 inline void vtkStructuredData::GetLocalStructuredCoordinates(
366 int ijk[3], int ext[6], int lijk[3], int)
367 {
368 lijk[0] = ijk[0] - ext[0];
369 lijk[1] = ijk[1] - ext[2];
370 lijk[2] = ijk[2] - ext[4];
371 }
372
373 //------------------------------------------------------------------------------
GetGlobalStructuredCoordinates(int lijk[3],int ext[6],int ijk[3],int)374 inline void vtkStructuredData::GetGlobalStructuredCoordinates(
375 int lijk[3], int ext[6], int ijk[3], int)
376 {
377 ijk[0] = ext[0] + lijk[0];
378 ijk[1] = ext[2] + lijk[1];
379 ijk[2] = ext[4] + lijk[2];
380 }
381
382 //------------------------------------------------------------------------------
ComputePointIdForExtent(int extent[6],int ijk[3],int)383 inline vtkIdType vtkStructuredData::ComputePointIdForExtent(
384 int extent[6], int ijk[3], int)
385 {
386 int dims[3];
387 vtkStructuredData::GetDimensionsFromExtent(extent, dims);
388
389 int lijk[3];
390 vtkStructuredData::GetLocalStructuredCoordinates(ijk, extent, lijk);
391
392 return vtkStructuredData::ComputePointId(dims, lijk);
393 }
394
395 //------------------------------------------------------------------------------
ComputeCellIdForExtent(int extent[6],int ijk[3],int)396 inline vtkIdType vtkStructuredData::ComputeCellIdForExtent(
397 int extent[6], int ijk[3], int)
398 {
399 int nodeDims[3];
400 vtkStructuredData::GetDimensionsFromExtent(extent, nodeDims);
401
402 int lijk[3];
403 vtkStructuredData::GetLocalStructuredCoordinates(ijk, extent, lijk);
404
405 return vtkStructuredData::ComputeCellId(nodeDims, lijk);
406 }
407
408 //------------------------------------------------------------------------------
ComputeCellStructuredCoords(const vtkIdType cellId,int dims[3],int ijk[3],int)409 inline void vtkStructuredData::ComputeCellStructuredCoords(
410 const vtkIdType cellId, int dims[3], int ijk[3], int)
411 {
412 vtkStructuredData::GetStructuredCoordinates(cellId,
413 dims[0] - 1, dims[1] - 1,
414 ijk[0], ijk[1], ijk[2]);
415 }
416
417 //------------------------------------------------------------------------------
ComputeCellStructuredCoordsForExtent(const vtkIdType cellIdx,int ext[6],int ijk[3],int)418 inline void vtkStructuredData::ComputeCellStructuredCoordsForExtent(
419 const vtkIdType cellIdx, int ext[6], int ijk[3], int)
420 {
421 int nodeDims[3];
422 vtkStructuredData::GetDimensionsFromExtent(ext, nodeDims);
423
424 int lijk[3];
425 vtkStructuredData::ComputeCellStructuredCoords(cellIdx, nodeDims, lijk);
426
427 vtkStructuredData::GetGlobalStructuredCoordinates(lijk, ext, ijk);
428 }
429
430 //------------------------------------------------------------------------------
ComputePointStructuredCoords(const vtkIdType ptId,int dim[3],int ijk[3],int)431 inline void vtkStructuredData::ComputePointStructuredCoords(
432 const vtkIdType ptId, int dim[3], int ijk[3], int)
433 {
434 vtkStructuredData::GetStructuredCoordinates(ptId, dim[0], dim[1],
435 ijk[0], ijk[1], ijk[2]);
436 }
437
438 //------------------------------------------------------------------------------
ComputePointStructuredCoordsForExtent(const vtkIdType ptId,int ext[6],int ijk[3],int)439 inline void vtkStructuredData::ComputePointStructuredCoordsForExtent(
440 const vtkIdType ptId, int ext[6], int ijk[3], int)
441 {
442 int nodeDims[3];
443 vtkStructuredData::GetDimensionsFromExtent(ext, nodeDims);
444
445 int lijk[3];
446 vtkStructuredData::ComputePointStructuredCoords(ptId, nodeDims, lijk);
447
448 vtkStructuredData::GetGlobalStructuredCoordinates(lijk, ext, ijk);
449 }
450
451 #endif
452
453 // VTK-HeaderTest-Exclude: vtkStructuredData.h
454