Source code for vtk_openCARP_methods_ibt.vtk_methods.mapper

from pathlib import Path

import numpy as np
import vtk
from scipy.spatial import KDTree
from vtkmodules.numpy_interface import dataset_adapter as dsa

from ..openCARP.exporting import write_to_pts
from ..vtk_methods.converters import vtk_to_numpy
from ..vtk_methods.exporting import vtk_unstructured_grid_writer, write_to_vtx
from ..vtk_methods.reader import vtx_reader, smart_reader


[docs] def point_array_mapper(mesh1, mesh2, idat): """ :param mesh1: :param mesh2: :param idat: Set to "all" to mapp all arrays, else choose a specific array :return: Mapped mesh """ pts1 = vtk_to_numpy(mesh1.GetPoints().GetData()) pts2 = vtk_to_numpy(mesh2.GetPoints().GetData()) meshNew = _point_array_mapper(idat, mesh1, mesh2, pts1, pts2) return meshNew.VTKObject
def _point_array_mapper(idat, mesh1, mesh2, pts1, pts2): """ :param idat: Set to "all" to mapp all arrays, else choose a specific array :param mesh1: :param mesh2: :param pts1: :param pts2: :return: """ tree = KDTree(pts1) dd, ii = tree.query(pts2, workers=-1) meshNew = dsa.WrapDataObject(mesh2) if idat == "all": for i in range(mesh1.GetPointData().GetNumberOfArrays()): data = vtk_to_numpy( mesh1.GetPointData().GetArray(mesh1.GetPointData().GetArrayName(i))) data2 = data[ii] data2 = np.where(np.isnan(data2), 10000, data2) meshNew.PointData.append(data2, mesh1.GetPointData().GetArrayName(i)) else: data = vtk_to_numpy(mesh1.GetPointData().GetArray(idat)) data2 = data[ii] meshNew.PointData.append(data2, idat) return meshNew
[docs] def cell_array_mapper(mesh1, mesh2, mesh2_name, idat): """ :param mesh1: Vtk mesh object :param mesh2: Vtk mesh object :param mesh2_name: :param idat: Set to "all" to mapp all arrays, else choose a specific array :return: Returns mesh and also stores it to disk with subfix "_with_data" """ filter_cell_centers = vtk.vtkCellCenters() filter_cell_centers.SetInputData(mesh1) filter_cell_centers.Update() centroids1 = filter_cell_centers.GetOutput().GetPoints() centroids1_array = vtk_to_numpy(centroids1.GetData()) filter_cell_centers = vtk.vtkCellCenters() filter_cell_centers.SetInputData(mesh2) filter_cell_centers.Update() centroids2 = filter_cell_centers.GetOutput().GetPoints() pts2 = vtk_to_numpy(centroids2.GetData()) meshNew = _cell_array_mapper(idat, mesh1, mesh2, centroids1_array, pts2) vtk_unstructured_grid_writer(f"{mesh2_name.split('.')[0]}_with_data.vtk", meshNew.VTKObject) return meshNew.VTKObject
def _cell_array_mapper(idat, mesh1, mesh2, array1, array2): """ :param idat: Set to "all" to mapp all arrays, else choose a specific array :param mesh1: :param mesh2: :param array1: :param array2: :return: """ tree = KDTree(array1) dd, ii = tree.query(array2, workers=-1) meshNew = dsa.WrapDataObject(mesh2) if idat == "all": for i in range(mesh1.GetCellData().GetNumberOfArrays()): data = vtk_to_numpy( mesh1.GetCellData().GetArray(mesh1.GetCellData().GetArrayName(i))) data2 = data[ii] meshNew.CellData.append(data2, mesh1.GetCellData().GetArrayName(i)) else: data = vtk_to_numpy(mesh1.GetCellData().GetArray(idat)) data2 = data[ii] meshNew.CellData.append(data2, idat) return meshNew
[docs] def mapp_ids_for_folder(source_folder, dest_folder, source_mesh, dest_mesh, debug=False): """ Maps all vtx files from one folder to another folder with two different meshes as a base. vtx files in source folder has to be originated from the source mesh. All the vtx files in the dest_folder will be in correspondence to the dest_mesh :param debug: If true all the vtx files will also be stored as .pts file for better inspection :param source_folder:Path to a folder with vtx files :param dest_folder: Path to a folder where the results are stored :param source_mesh: original vtk mesh :param dest_mesh: mesh for the reference of the newly generated points :return: """ num_converted_files = 0 folder = Path(source_folder) for file in folder.glob("ids_*.vtx"): if file.is_file(): # Ensure it's a file print(f"Processing file: {file.name}") # Read the content of the .vtx file vtx_data = vtx_reader(file) remapped_ids = remap_ids(source_mesh, dest_mesh, vtx_data) write_to_vtx(f"{dest_folder}/{file.name}", remapped_ids) num_converted_files += 1 if debug: write_to_pts(f"{dest_folder}/{file.name}.pts", [dest_mesh.GetPoint(closest_id) for closest_id in remapped_ids] ) print(f"Number of converted files: {num_converted_files}")
[docs] def remap_ids(source_mesh, dest_mesh, source_point_ids): """ Maps source point_id_s coming from the source_mesh to ids from the dest_mesh. :param source_mesh: vtk mesh :param dest_mesh: vtk mesh :param source_point_ids: array :return: Array with the new ids """ locator = vtk.vtkPointLocator() locator.SetDataSet(dest_mesh) locator.BuildLocator() new_ids = [] for source_id in source_point_ids: point = source_mesh.GetPoint(source_id) closest_id = locator.FindClosestPoint(point) new_ids.append(closest_id) return new_ids
[docs] def ids_to_pts(ids, mesh): """ Converts ids to pts which can be exported to a pts file :param ids: The point ids for the mesh :param mesh: :return: """ points = [] for id in ids: points.append(mesh.GetPoint(id)) return points
[docs] def vtx_to_pts(vtx_filename, pts_filename, mesh_filename): ids = vtx_reader(vtx_filename) mesh = smart_reader(mesh_filename) points = ids_to_pts(ids, mesh) write_to_pts(pts_filename, points)