Skip to content

Results & Validation

This page documents the result and validation classes returned by mmgpy operations.

RemeshResult

Every remeshing operation returns a RemeshResult dataclass with statistics:

mmgpy.RemeshResult dataclass

RemeshResult(
    vertices_before: int,
    vertices_after: int,
    elements_before: int,
    elements_after: int,
    triangles_before: int,
    triangles_after: int,
    edges_before: int,
    edges_after: int,
    quality_min_before: float,
    quality_min_after: float,
    quality_mean_before: float,
    quality_mean_after: float,
    duration_seconds: float,
    warnings: tuple[str, ...],
    return_code: int,
)

Statistics from a remeshing operation.

This class captures mesh topology changes, quality metrics, timing, and any warnings from the remeshing operation.

Attributes

vertices_before : int Number of vertices before remeshing. vertices_after : int Number of vertices after remeshing. elements_before : int Number of primary elements (tetrahedra for 3D, triangles for 2D/surface). elements_after : int Number of primary elements after remeshing. triangles_before : int Number of triangles (boundary for 3D, all for 2D/surface). triangles_after : int Number of triangles after remeshing. edges_before : int Number of edges before remeshing. edges_after : int Number of edges after remeshing. quality_min_before : float Minimum element quality before remeshing (0-1 scale). quality_min_after : float Minimum element quality after remeshing. quality_mean_before : float Mean element quality before remeshing. quality_mean_after : float Mean element quality after remeshing. duration_seconds : float Wall-clock time for the remeshing operation in seconds. Measures only the MMG library call, excluding stats collection overhead. warnings : tuple[str, ...] Any warnings from MMG (non-fatal issues). Contains warning messages captured from MMG's stderr output during remeshing. Common warnings include edge size clamping, geometric constraint violations, etc. return_code : int MMG return code (0 = success). Note: If remeshing fails, an exception is raised before RemeshResult is created, so this will always be 0 for successfully returned results. Included for completeness and potential future use with partial failure modes.

Examples

mesh = MmgMesh3D(vertices, tetrahedra) result = mesh.remesh(hmax=0.1) print(result) RemeshResult( vertices: 100 -> 250 (+150) elements: 400 -> 1200 (+800) quality: 0.450 -> 0.780 (173.3%) duration: 0.15s ) result.success True result.quality_improvement 1.733...

vertex_change property

vertex_change: int

Net change in vertex count.

element_change property

element_change: int

Net change in element count.

triangle_change property

triangle_change: int

Net change in triangle count.

edge_change property

edge_change: int

Net change in edge count.

quality_improvement property

quality_improvement: float

Quality improvement ratio (mean_after / mean_before).

Returns 1.0 if both values are zero (no change), inf if only before is zero, and the actual ratio otherwise.

success property

success: bool

Whether remeshing completed successfully.

__str__

__str__() -> str

Return a readable string representation.

options: show_root_heading: true

Usage

import mmgpy

mesh = mmgpy.read("input.mesh")
result = mesh.remesh(hmax=0.1)

# Access statistics
print(f"Vertices: {result.vertices_before} -> {result.vertices_after}")
print(f"Elements: {result.elements_before} -> {result.elements_after}")
print(f"Triangles: {result.triangles_before} -> {result.triangles_after}")
print(f"Edges: {result.edges_before} -> {result.edges_after}")

# Quality metrics
print(f"Min quality: {result.quality_min_before:.3f} -> {result.quality_min_after:.3f}")
print(f"Mean quality: {result.quality_mean_before:.3f} -> {result.quality_mean_after:.3f}")

# Timing
print(f"Duration: {result.duration_seconds:.2f}s")

# Warnings from MMG
for warning in result.warnings:
    print(f"Warning: {warning}")

# Return code
print(f"Return code: {result.return_code}")

Validation Classes

ValidationReport

mmgpy.ValidationReport dataclass

ValidationReport(
    is_valid: bool,
    issues: tuple[ValidationIssue, ...],
    quality: QualityStats | None,
    mesh_type: str,
)

Complete validation report for a mesh.

Attributes

is_valid : bool True if no errors were found (warnings are OK). issues : tuple[ValidationIssue, ...] All validation issues found. quality : QualityStats | None Quality statistics (None if quality check was skipped). mesh_type : str Type of mesh that was validated.

errors property

errors: list[ValidationIssue]

Get all error-level issues.

warnings property

warnings: list[ValidationIssue]

Get all warning-level issues.

__str__

__str__() -> str

Return a human-readable summary.

options: show_root_heading: true

ValidationIssue

mmgpy.ValidationIssue dataclass

ValidationIssue(
    severity: IssueSeverity,
    check_name: str,
    message: str,
    element_ids: tuple[int, ...] = tuple(),
)

A single validation issue found in the mesh.

Attributes

severity : IssueSeverity Whether this is an error (mesh unusable) or warning (may cause issues). check_name : str Name of the validation check that found this issue. message : str Human-readable description of the issue. element_ids : tuple[int, ...] Indices of affected elements (empty for global issues).

options: show_root_heading: true

QualityStats

mmgpy.QualityStats dataclass

QualityStats(
    min: float,
    max: float,
    mean: float,
    std: float,
    histogram: tuple[tuple[str, int], ...],
)

Statistics about mesh element quality.

Quality values are normalized to [0, 1] where 1 is a perfect element.

Attributes

min : float Minimum element quality. max : float Maximum element quality. mean : float Mean element quality. std : float Standard deviation of element quality. histogram : tuple[tuple[str, int], ...] Quality distribution as (bin_label, count) pairs.

below_threshold

below_threshold(threshold: float) -> int

Count elements below a quality threshold.

Parameters

threshold : float Quality threshold (0-1).

Returns

int Number of elements with quality below threshold.

options: show_root_heading: true

IssueSeverity

mmgpy.IssueSeverity

Bases: Enum

Severity level for validation issues.

options: show_root_heading: true

ValidationError

mmgpy.ValidationError

ValidationError(report: ValidationReport)

Bases: Exception

Exception raised when strict validation fails.

Initialize with a validation report.

options: show_root_heading: true

Validation Usage

Quick Validation

import mmgpy

mesh = mmgpy.read("input.mesh")

# Returns True/False
if mesh.validate():
    print("Mesh is valid")
else:
    print("Mesh has issues")

Detailed Validation

report = mesh.validate(detailed=True)

print(f"Valid: {report.is_valid}")
print(f"Vertices: {report.n_vertices}")
print(f"Elements: {report.n_elements}")
print(f"Triangles: {report.n_triangles}")

# Quality statistics
print(f"Quality min: {report.quality.min:.3f}")
print(f"Quality max: {report.quality.max:.3f}")
print(f"Quality mean: {report.quality.mean:.3f}")
print(f"Quality std: {report.quality.std:.3f}")

# Issues
for issue in report.issues:
    print(f"[{issue.severity.name}] {issue.message}")

Strict Validation

from mmgpy import ValidationError

try:
    mesh.validate(strict=True)
    print("Mesh passed strict validation")
except ValidationError as e:
    print(f"Validation failed: {e}")
    for issue in e.report.issues:
        print(f"  - {issue.message}")

Selective Validation

# Only check geometry
report = mesh.validate(
    detailed=True,
    check_geometry=True,
    check_topology=False,
    check_quality=False,
)

# Only check quality with custom threshold
report = mesh.validate(
    detailed=True,
    check_geometry=False,
    check_topology=False,
    check_quality=True,
    min_quality=0.2,  # Custom threshold
)

Complete Example

import mmgpy
from mmgpy import ValidationError

# Load mesh
mesh = mmgpy.read("input.mesh")

# Initial validation
initial = mesh.validate(detailed=True)
print(f"Initial quality: {initial.quality.mean:.3f}")

if not initial.is_valid:
    print("Initial mesh has issues:")
    for issue in initial.issues:
        print(f"  - {issue.message}")

# Remesh
result = mesh.remesh(hmax=0.1, verbose=-1)

# Post-remesh validation
try:
    mesh.validate(strict=True)
    print("Remeshed mesh is valid")
except ValidationError as e:
    print(f"Remeshed mesh has issues: {len(e.report.issues)}")

# Final report
final = mesh.validate(detailed=True)
print(f"\nQuality improved: {initial.quality.mean:.3f} -> {final.quality.mean:.3f}")
print(f"Elements: {initial.n_elements} -> {final.n_elements}")