Source code for lyceanem.utility.mesh_functions

import meshio
import pyvista as pv


[docs] def pyvista_to_meshio(polydata_object): """ Convert a pyvista object to a meshio object, if pyvista >=0.45, use to_meshio method. Parameters ---------- polydata_object : pyvista.PolyData or pyvista.UnstructuredGrid The pyvista object to convert. Returns ------- meshio_object : :type:`meshio.Mesh` The converted meshio object. """ # from packaging.version import parse as parse_version # if parse_version(pv.__version__)>=parse_version("0.45.0"): # meshio_object=pv.from_meshio(polydata_object) # else: if type(polydata_object) == pv.core.pointset.UnstructuredGrid: cells = id_cells(polydata_object.cells) else: cells = id_cells(polydata_object.faces) meshio_object = meshio.Mesh( points=polydata_object.points, cells=cells, point_data=polydata_object.point_data, ) return meshio_object
[docs] def meshio_to_pyvista(meshio_object): """ Convert a meshio object to a pyvista object. Parameters ---------- meshio_object : :type:`meshio.Mesh` The meshio object to convert. Returns ------- pyvista_object : :type:`pyvista.PolyData` or :type:`pyvista.UnstructuredGrid` The converted pyvista object. """ import numpy as np for cell in meshio_object.cells: if cell.type == "triangle": tris = cell.data faces = np.hstack((np.ones((tris.shape[0], 1), dtype=int) * 3, tris)) polydata_object = pv.PolyData(meshio_object.points, faces=faces) for key in meshio_object.point_data.keys(): polydata_object.point_data[key] = meshio_object.point_data[key] for key in meshio_object.cell_data.keys(): polydata_object.cell_data[key] = meshio_object.cell_data[key][0] return polydata_object
[docs] def id_cells(faces): """ Identify cell ids Parameters ---------- faces : numpy.ndarray of int The faces of the mesh. Returns ------- meshio_cells : list A list of tuples containing the cell type and the cell data. """ # temp_faces=copy.deepcopy(faces) cell_types = {1: "vertex", 2: "line", 3: "triangle", 4: "quad"} cells = {"vertex": [], "line": [], "triangle": [], "quad": []} moving_index = 0 while moving_index <= faces.shape[0] - 1: face_num = faces[moving_index] temp_array = faces[moving_index + 1 : moving_index + face_num + 1] cells[cell_types[face_num]].append(temp_array.tolist()) moving_index += face_num + 1 # while (temp_faces.shape[0]>=1): # trim_num =temp_faces[0] # if trim_num>3: # print("Cell Face Error") # temp_array =temp_faces[1:trim_num +1] # cells[cell_types[trim_num]].append(temp_array.tolist()) # temp_faces =np.delete(temp_faces ,np.arange(0 ,trim_num +1)) meshio_cells = [] for key in cells: if len(cells[key]) > 0: meshio_cells.append((key, cells[key])) return meshio_cells
[docs] def points2pointcloud(xyz): """ turns numpy array of xyz data into a meshio format point cloud Parameters ---------- xyz : numpy.ndarray of float The xyz data to convert. The shape of the array should be (n, 3) or (n, 1, 3). If the shape is (n, 1, 3), it will be reshaped to (n, 3). Returns ------- new_point_cloud : :type:`meshio.Mesh` The converted meshio point cloud. """ import numpy as np if xyz.shape[1] == 3: reshaped = xyz else: reshaped = xyz.reshape((int(len(xyz.ravel()) / 3), 3)) # assume mean of xyz is centre, and normals are outwards facing from center. center = np.mean(xyz, axis=0) normals = reshaped - center mesh_points = meshio.Mesh( points=reshaped, cells=[ ( "vertex", np.array( [ [ i, ] for i in range(reshaped.shape[0]) ] ), ) ], point_data={ "Normals": normals / np.linalg.norm(normals, axis=1).reshape(-1, 1) }, ) return mesh_points