“”” API Reference: Mesh Module ===========================

This module provides classes and functions for converting block models into triangulated surface geometry and exporting to standard formats.

Classes#

TriangleMesh#

class parq_blockmodel.mesh.TriangleMesh(vertices, faces, vertex_attributes=None, face_attributes=None, vertex_ijk=None, face_ijk=None, metadata=None)[source]#

Representation of a triangle mesh with optional attributes.

This is the internal mesh format used by the mesh module. It can be serialized to PLY (lossless) or GLB (derived) formats.

vertices#

Vertex coordinates, shape (n_vertices, 3) in world space.

Type:

np.ndarray

faces#

Triangle face indices, shape (n_faces, 3). Each row is a CCW-ordered triangle when viewed from the exterior (right-handed coordinates).

Type:

np.ndarray

vertex_attributes#

Per-vertex scalar attributes, e.g. {“grade”: (n_vertices,), “density”: (n_vertices,)}.

Type:

dict[str, np.ndarray]

face_attributes#

Per-face scalar attributes, e.g. {“rock_type”: (n_faces,)}.

Type:

dict[str, np.ndarray]

vertex_ijk#

Logical (i, j, k) indices for each vertex, shape (n_vertices, 3). Useful for tracing back to block model.

Type:

Optional[np.ndarray]

face_ijk#

Logical (i, j, k) indices for each face (typically the block containing it), shape (n_faces, 3).

Type:

Optional[np.ndarray]

metadata#

Arbitrary metadata, e.g. CRS, units, author, etc.

Type:

dict

Represents a triangle mesh with optional vertex and face attributes.

Attributes#

verticesnp.ndarray

Vertex coordinates, shape (n_vertices, 3) in world space.

facesnp.ndarray

Triangle face indices, shape (n_faces, 3).

vertex_attributesdict[str, np.ndarray]

Per-vertex attributes (e.g., grades, rock types).

face_attributesdict[str, np.ndarray]

Per-face attributes.

vertex_ijknp.ndarray, optional

Logical (i, j, k) indices for vertices.

face_ijknp.ndarray, optional

Logical (i, j, k) indices for faces.

metadatadict

Geometry and export metadata.

Methods#

validate()

Validate mesh integrity.

n_vertices

Number of vertices.

n_faces

Number of faces.

face_attributes: dict[str, ndarray[Any, dtype[TypeVar(_ScalarType_co, bound= generic, covariant=True)]]] = None#
face_ijk: Optional[ndarray[Any, dtype[int64]]] = None#
faces: ndarray[Any, dtype[int64]]#
metadata: Optional[dict] = None#
property n_faces: int#

Number of faces (triangles).

property n_vertices: int#

Number of vertices.

validate()[source]#

Validate mesh integrity.

Raises:

ValueError – If mesh is malformed (e.g., vertices not 3D, faces have invalid indices).

Return type:

None

vertex_attributes: dict[str, ndarray[Any, dtype[TypeVar(_ScalarType_co, bound= generic, covariant=True)]]] = None#
vertex_ijk: Optional[ndarray[Any, dtype[int64]]] = None#
vertices: ndarray[Any, dtype[floating]]#

BlockMeshGenerator#

class parq_blockmodel.mesh.BlockMeshGenerator(geometry)[source]#

Convert a block model to a triangulated surface mesh.

This class generates vertex and face arrays from a RegularGeometry and optional block attribute data. Supports both rotated and non-rotated geometries, sparse and dense block layouts, and surface-only vs. full interior mesh generation.

Coordinates are always in world space (right-handed), with rotation applied via the RegularGeometry’s axis vectors (axis_u, axis_v, axis_w).

Parameters:

geometry (RegularGeometry) – The block model geometry defining corner, block_size, shape, and axis orientation.

geometry#

The block model geometry.

Type:

RegularGeometry

Notes

All generated triangles use counter-clockwise (CCW) winding order when viewed from the exterior (right-hand rule). This ensures compatibility with standard 3D graphics renderers and PLY/GLB viewers.

Generates triangle meshes from block model geometry and data.

Parameters#

geometryRegularGeometry

Block model geometry.

Methods#

triangulate(block_data, surface_only, sparse)

Generate a triangle mesh.

block_corners_local()

Get local cube corner coordinates.

block_vertices_xyz(i, j, k)

Get world coordinates of block corners.

cube_faces_ccw()

Get cube face triangles with CCW winding.

block_corners_local()[source]#

Get the 8 corner offsets for a unit cube in local (i, j, k) space.

Returns a (8, 3) array where each row is a corner offset: (0,0,0), (1,0,0), (0,1,0), (1,1,0), (0,0,1), (1,0,1), (0,1,1), (1,1,1).

Returns:

Shape (8, 3), corner offsets in local space.

Return type:

np.ndarray

block_vertices_xyz(i, j, k)[source]#

Get the 8 vertices of a block in world coordinates.

Parameters:
  • i (int) – Logical block indices.

  • j (int) – Logical block indices.

  • k (int) – Logical block indices.

Returns:

Shape (8, 3), corner coordinates in world space.

Return type:

np.ndarray

cube_faces_ccw()[source]#

Get the 6 faces of a cube with CCW winding (right-hand rule).

Each face is a pair of triangles sharing an edge. Winding order is such that the outward normal points away from the cube center.

Local vertex numbering:

0: (0,0,0) 1: (1,0,0) 2: (0,1,0) 3: (1,1,0) 4: (0,0,1) 5: (1,0,1) 6: (0,1,1) 7: (1,1,1)

Returns:

Shape (12, 3), 12 triangles (2 per face, 6 faces).

Return type:

np.ndarray

surface_faces_ccw()[source]#

Get only the exterior surface faces of a cube.

For a sparse block model, we typically want only faces on the boundary of the model. This method returns which faces are “exterior” in a dense grid context. When sparse blocks are present, we’ll filter out internal faces via connectivity checks.

Returns the same 12 triangles as cube_faces_ccw(), but this is a placeholder for future boundary detection logic.

Returns:

Shape (12, 3), exterior triangles.

Return type:

np.ndarray

triangulate(block_data=None, surface_only=True, sparse=None)[source]#

Generate a triangle mesh from block model data.

Parameters:
  • block_data (pd.DataFrame, optional) – Block model data with columns like “i”, “j”, “k”, “grade”, “density”, etc. If provided, attributes will be mapped to the mesh. If None, only geometry is returned with no attribute data.

  • sparse (bool, optional) – If True, include only blocks present in block_data. If False or None, generate the full dense mesh. If sparse=True but block_data is None, only non-empty blocks are included.

  • surface_only (bool, default True) – If True, include only exterior surface faces (shared faces with adjacent blocks are removed). If False, include all faces (interior voids remain empty). Only meaningful for sparse models.

Returns:

The generated mesh with vertices, faces, and optional attributes.

Return type:

TriangleMesh

Raises:

ValueError – If block_data is incompatible with the geometry.

Functions#

PLY Format Functions#

GLB Format Functions#

ParquetBlockModel Methods#

These methods are added to ParquetBlockModel:

Examples#

Generate and inspect mesh:

from parq_blockmodel import ParquetBlockModel
from pathlib import Path

pbm = ParquetBlockModel(Path("model.pbm"))
mesh = pbm.triangulate(attributes=["grade"])

print(f"Vertices: {mesh.n_vertices}")
print(f"Faces: {mesh.n_faces}")
print(f"Attributes: {list(mesh.vertex_attributes.keys())}")

Export to PLY (lossless):

pbm.to_ply("model.ply", attributes=["grade", "density"])

Export to GLB with colors:

pbm.to_glb("model.glb", texture_attribute="grade", colormap="viridis")

Handle sparse models:

# Surface-only mesh for sparse model (common in mining)
mesh = pbm.triangulate(surface_only=True, sparse=True)

Notes#

Coordinate Systems

All mesh coordinates are in world space with units from the underlying block model. Rotations are applied via RegularGeometry’s axis vectors.

Right-handedness

Mesh triangles use counter-clockwise (CCW) winding order when viewed from the exterior (right-hand rule), ensuring compatibility with standard 3D viewers.

Sparse Models

For block models with missing cells, use surface_only=True (default) to generate only exterior faces, improving performance and visual clarity.

Attribute Preservation

Block attributes are preserved as per-vertex and per-face properties in both PLY and GLB formats. Categorical attributes are encoded as integers with metadata mapping.

See Also#

“””