Source code for underworld3.utilities.read_medit_ascii

# ### Read medit (.mesh) ascii file
# #### Return mesh data type

from contextlib import contextmanager  # For creating a context manager
from ctypes import c_double, c_float  # For handling C data types in Python
import numpy as np
import re


# +
# Define custom exceptions for error handling


class ReadError(Exception):
    pass


class WriteError(Exception):
    pass


class CorruptionError(Exception):
    pass


# -


def is_buffer(obj, mode):
    """
    Function to check if an object is a buffer and
    supports the required mode (read/write)
    """
    return ("r" in mode and hasattr(obj, "read")) or ("w" in mode and hasattr(obj, "write"))


@contextmanager
def open_file(path_or_buf, mode="r"):
    """Context manager for opening a file or handling an existing buffer"""
    if is_buffer(path_or_buf, mode):
        yield path_or_buf
    else:
        with open(path_or_buf, mode) as f:
            yield f


[docs] def read_medit_ascii(filename, mesh_data_name): """ Function to read a medit mesh file in ascii format. Return mesh data and their indices if found. """ with open_file(filename) as f: mesh = read_ascii_buffer(f, mesh_data_name) return mesh
def print_medit_mesh_info(file_path): """print medit mesh info""" mesh_data_name_list = [] with open(file_path, "r") as f: while True: line = f.readline() if not line: # End of file break line = line.strip() if len(line) == 0 or line[0] == "#": continue items = line.split() # Check for alphabetic characters in the first item if items[0].isalpha(): # Process the MeshVersionFormatted line if items[0] == "MeshVersionFormatted": version = items[1] print("Mesh Version Format:", version) # Process the Dimension line elif items[0] == "Dimension": if len(items) >= 2: dim = int(items[1]) else: dim = int(f.readline().strip()) print("Dimension:", dim) # Print other lines that contain alphabetic characters else: if line == "End": pass else: mesh_data_name_list.append(line) # print(f'"{line}"') size = int(f.readline().strip()) print(f"Number of {line}:", size) else: # Ignore lines that do not start with an alphabetic character continue print("Mesh file contains following data types:", mesh_data_name_list) # taken from meshio def read_ascii_buffer(f, mesh_data_name, int_type=np.int32): points_in_mesh_data = { "Edges": ("line", 2), "Triangles": ("triangle", 3), "Quadrilaterals": ("quad", 4), "Tetrahedra": ("tetra", 4), "Prisms": ("wedge", 6), "Pyramids": ("pyramid", 5), "Hexahedra": ("hexahedron", 8), # Frey "Hexaedra": ("hexahedron", 8), # Dobrzynski } while True: line = f.readline() if not line: break line = line.strip() if len(line) == 0 or line[0] == "#": continue items = line.split() if items[0] == "MeshVersionFormatted": version = items[1] dtype = {"0": c_float, "1": c_float, "2": c_double}[version] elif items[0] == "Dimension": if len(items) >= 2: dim = int(items[1]) else: # e.g. Dimension\n3, where the number of dimensions is on the next line dim = int(int(f.readline())) # return vertices elif items[0] == mesh_data_name and items[0] == "Vertices": if dim <= 0: raise ReadError() if dtype is None: raise ReadError("Expected `MeshVersionFormatted` before `Vertices`") num_verts = int(f.readline()) data = np.fromfile(f, count=num_verts * (dim + 1), dtype=dtype, sep=" ").reshape( num_verts, dim + 1 ) break # return cells, triangles, edges elif items[0] == mesh_data_name and items[0] in ("Tetrahedra", "Triangles", "Edges"): mesh_data_type, points_per_cell = points_in_mesh_data[items[0]] num_cells = int(f.readline()) # The first value is the number of elements data = np.fromfile( f, count=num_cells * (points_per_cell + 1), dtype=int_type, sep=" " ).reshape(num_cells, points_per_cell + 1) break # return corners, RequiredVertices elif items[0] == mesh_data_name and items[0] in ("Corners", "RequiredVertices", "Ridges"): size = int(f.readline()) data = np.fromfile(f, count=size, dtype=int_type, sep=" ") break # return normals, tangents elif items[0] == mesh_data_name and items[0] in ("Normals", "Tangents"): size = int(f.readline()) data = np.fromfile(f, count=size * dim, dtype=dtype, sep=" ").reshape(size, dim) break # return normalatvertices, tangentatvertices elif items[0] == mesh_data_name and items[0] in ("NormalAtVertices", "TangentAtVertices"): size = int(f.readline()) data = np.fromfile(f, count=size * 2, dtype=int_type, sep=" ").reshape(size, 2) break # checking whether file had ended or not else: if items[0] == "End": print("Reached end of the file. Entered mesh data is not found") return if mesh_data_name in ("Vertices", "Normals", "Tangents"): if data.shape[1] == dim: return data else: return data[:, :dim], data[:, dim].astype(int_type) else: # adapt for 0-base if mesh_data_name in ("Tetrahedra", "Triangles", "Edges"): return data[:, :points_per_cell] - 1, data[:, -1] else: return data - 1