porescene.utility module

class porescene.utility.CompassDirection(*values)[source]

Bases: Enum

EAST = 'E'
NORTH = 'N'
NORTHEAST = 'NE'
NORTHWEST = 'NW'
SOUTH = 'S'
SOUTHEAST = 'SE'
SOUTHWEST = 'SW'
WEST = 'W'
class porescene.utility.Mesh(vertices, faces, name='object')[source]

Bases: object

A simple container pairing a mesh’s vertices with its faces.

property faces: ndarray

(M, K) array of vertex indices, one row per polygon.

property name: str

Name of the mesh.

property vertices: ndarray

(N, 3) array of vertex coordinates.

class porescene.utility.MultiplicationSymbol(*values)[source]

Bases: Enum

CROSS = '×'
DOT = '·'
class porescene.utility.Orientation(*values)[source]

Bases: Enum

HORIZONTAL = 'H'
VERTICAL = 'V'
class porescene.utility.UnitExponentMetric(*values)[source]

Bases: Enum

ATTO = -18
CENTI = -2
DECA = 1
DECI = -1
EXA = 18
FEMTO = -15
GIGA = 9
HECTO = 2
KILO = 3
MEGA = 6
MICRO = -6
MILLI = -3
NANO = -9
PETA = 15
PICO = -12
QUECTO = -30
QUETTA = 30
RONNA = 27
RONTO = -27
TERA = 12
YOCTO = -24
YOTTA = 24
ZEPTO = -21
ZETTA = 21
class porescene.utility.UnitPrefixMetric(*values)[source]

Bases: Enum

ATTO = 'a'
CENTI = 'c'
DECA = 'da'
DECI = 'd'
EXA = 'E'
FEMTO = 'f'
GIGA = 'G'
HECTO = 'h'
KILO = 'k'
MEGA = 'M'
MICRO = 'µ'
MILLI = 'm'
NANO = 'n'
PETA = 'P'
PICO = 'p'
QUECTO = 'q'
QUETTA = 'Q'
RONNA = 'R'
RONTO = 'r'
TERA = 't'
YOCTO = 'y'
YOTTA = 'Y'
ZEPTO = 'z'
ZETTA = 'Z'
porescene.utility.n_equidistant(lst, n)[source]
porescene.utility.suppress_stdout()[source]

Silences stdout at the OS file-descriptor level.

Return type:

Generator[None]

porescene.utility.svg2png(pth, crop=True)[source]

Convert a SVG file to PNG.

Uses resvg_py for the conversion, which ships as a self-contained wheel, so pip install pulls in everything and no external software is required. With crop=True the result is trimmed to its visible content by removing the surrounding transparent margin.

Note that resvg_py only renders content inside the SVG viewport; anything drawn beyond the root <svg> width/height is clipped before the crop and cannot be recovered.

Parameters:
  • pth (Path) – Path to the file to be converted.

  • crop (bool) – Trim the PNG to the bounding box of its non-transparent pixels.

Return type:

Path

porescene.utility.volume2mesh(img, voxel_size=(1.0, 1.0, 1.0), labels=1, *, per_label=False, swap_axes=False, name='object')[source]
Overloads:
  • img (np.ndarray), voxel_size (float | Sequence[float]), labels (int | Sequence[int] | np.ndarray), per_label (Literal[False]), swap_axes (bool), name (str) → Mesh

  • img (np.ndarray), voxel_size (float | Sequence[float]), labels (int | Sequence[int] | np.ndarray), per_label (Literal[True]), swap_axes (bool), name (str) → dict[int, Mesh]

Builds a rectangular (quad) surface mesh from a labeled voxel image.

Extracts the axis-aligned boundary faces of the voxels whose label is included in labels – every face between a selected voxel and a non-selected neighbour (or the volume border) – as unit squares scaled by the voxel size. Coincident vertices are merged, so each position is stored once and shared between faces.

Parameters:
  • img (ndarray) – 2D or 3D integer array of voxel labels. A 2D image is treated as a single slice, one voxel thick along the third axis.

  • voxel_size (float | Sequence[float]) – Edge length of a voxel. A scalar applies to all three axes; a 3-element sequence gives the length along x, y and z, by default (1.0, 1.0, 1.0).

  • labels (int | Sequence[int] | ndarray) – Label value(s) to include in the mesh, by default 1.

  • per_label (bool) – If False (default), all selected labels are meshed into a single surface. If True, a separate mesh is built per label and a {label: Mesh} mapping is returned.

  • swap_axes (bool) – If True, swaps the first and third axes of img before meshing, leaving the second axis untouched, by default False. This compensates for the axis-order mismatch between MATLAB’s column-major and numpy’s row-major array storage (see the corresponding swap_axes option of porescene.model.PoreNetwork.from_mat()): a voxel image loaded straight from a .mat file has its first and third (spatial) axes swapped relative to the coordinate frame the file’s own position variables (e.g. pos_p) were written in. Enable this to build the mesh in that same, un-swapped coordinate frame, matching position data imported with swap_axes=False.

  • name (str) – Name assigned to the resulting mesh. In per_label mode the label is appended as "{name}_{label}". By default "object".

Returns:

For a single mesh, a Mesh whose vertices is an (N, 3) float array and faces an (M, 4) integer array of quad vertex indices. With per_label=True, a {label: Mesh} dict.

Return type:

Mesh | dict[int, Mesh]