|
| 1 | +import numpy as np |
| 2 | +import vtk |
| 3 | +from pathlib import Path |
| 4 | +import pyvista as pv |
| 5 | + |
| 6 | + |
| 7 | +def form3DGrid(coords_array, connectivity_array) -> pv.UnstructuredGrid: |
| 8 | + """Create 3D VTK UnstructuredGrid from coordinates and connectivity |
| 9 | +
|
| 10 | + Currently supports tet grids, mixed tet/pyramid/hex grids. |
| 11 | +
|
| 12 | + Parameters |
| 13 | + ---------- |
| 14 | + coords_array : numpy.ndarray |
| 15 | + Coordinates of the points. Shape in (nPoints,2). |
| 16 | + connectivity_array : numpy.ndarray |
| 17 | + Connectivity array of the cells. Shape is (nCells,PointsPerCell). The |
| 18 | + index of points should start from 0. The type of cell will be inferred |
| 19 | + based on the number of points per cell. Mixed meshes inferred by |
| 20 | + repeated node IDs in a single element. |
| 21 | +
|
| 22 | + Returns |
| 23 | + ------- |
| 24 | + pv.UnstructuredGrid |
| 25 | + Pyvista UnstructuredGrid object with the grid loaded. |
| 26 | + """ |
| 27 | + nCells = connectivity_array.shape[0] |
| 28 | + nPnts = connectivity_array.shape[1] |
| 29 | + cell_type = None |
| 30 | + if nPnts == 4: |
| 31 | + cell_type = vtk.VTK_TETRA # ==int(10) |
| 32 | + elif nPnts == 8: |
| 33 | + tetCells = connectivity_array[:,3] == connectivity_array[:,4] |
| 34 | + pyrCells = (connectivity_array[:,4] == connectivity_array[:,5]) & ~tetCells |
| 35 | + if not np.any(pyrCells + tetCells): # not a mixed mesh |
| 36 | + cell_type = vtk.VTK_HEXAHEDRON # ==int(12) |
| 37 | + else: |
| 38 | + raise ValueError('This connectivity file has the wrong number of points.' |
| 39 | + ' Must be either 4 or 8 points per cell, this has {}'.format(nPnts)) |
| 40 | + |
| 41 | + if cell_type: |
| 42 | + connectivity_array = np.hstack((np.ones((nCells,1), dtype=np.int64)*nPnts, connectivity_array)) |
| 43 | + offsets = np.arange(0, connectivity_array.size+1, nPnts+1, dtype=np.int64) |
| 44 | + cell_types = np.ones(nCells, dtype=np.int64) * cell_type |
| 45 | + else: # mixed mesh |
| 46 | + hexCells = np.invert(tetCells + pyrCells) |
| 47 | + cell_types = tetCells*vtk.VTK_TETRA + pyrCells*vtk.VTK_PYRAMID + hexCells*vtk.VTK_HEXAHEDRON |
| 48 | + offset = tetCells*np.int64(4) + pyrCells*np.int64(5) + hexCells*np.int64(8) |
| 49 | + |
| 50 | + connectivity_array[tetCells, 4:] = np.int64(-1) |
| 51 | + connectivity_array[pyrCells, 5:] = np.int64(-1) |
| 52 | + connectivity_array = np.hstack((offset[:,None], connectivity_array)) |
| 53 | + connectivity_array = connectivity_array[connectivity_array != -1] |
| 54 | + |
| 55 | + offsets = np.roll(np.cumsum(offset+1), 1) |
| 56 | + offsets[0] = 0 |
| 57 | + |
| 58 | + grid = pv.UnstructuredGrid(offsets, connectivity_array, cell_types, coords_array) |
| 59 | + |
| 60 | + return grid |
0 commit comments