GeoSpec
engine 0.4.0
Matcher reference

Matcher reference

Every capability in the engine's registry, with its fields, admitted geometry, refusal codes and a passing and a refused example in TypeScript and Python.

Open Markdown

Each capability in the engine's registry has one section in this reference. A matcher is a capability's method on expectGeo (expect_geo in Python); a claim is one call of it, which the engine answers passed, failed or refused. The table is generated from the registry at build time and spells each name for the language you are reading; each name links to its section, and the cheat sheet lists every capability on one page.

An assertion answers passed, failed or refused, under either polarity. A query reports what the engine measured and accepts positive polarity only. Reads faces means the claim measures BRep faces or edges, so a STEP subject whose faces carry no surface refuses it.

CapabilityKindReads faces
toHaveBoundingBoxto_have_bounding_boxAssertionYes
toHaveConnectedComponentsto_have_connected_componentsAssertionYes
toBeWatertightto_be_watertightAssertionYes
toHaveNoComponentInterferenceto_have_no_component_interferenceAssertionYes
toHaveAssemblyOccurrencesto_have_assembly_occurrencesAssertionYes
toHaveSpatialRelationshipsto_have_spatial_relationshipsAssertionYes
toHaveMeshIntegrityto_have_mesh_integrityAssertionYes
toHaveNoDiagnosticsto_have_no_diagnosticsAssertionNo
toHaveSurfaceAreato_have_surface_areaAssertionYes
toHaveVolumeto_have_volumeAssertionYes
toHaveMassto_have_massAssertionYes
toHaveCenterOfMassto_have_center_of_massAssertionYes
toBeValidBrepto_be_valid_brepAssertionYes
toHaveTopologyCountsto_have_topology_countsAssertionYes
toHaveStepUnitsto_have_step_unitsAssertionNo
toHaveProductStructureto_have_product_structureAssertionNo
toHavePlanarFaceto_have_planar_faceAssertionYes
toHaveCylindricalFaceto_have_cylindrical_faceAssertionYes
toHaveCircularHoleto_have_circular_holeAssertionYes
toHaveCircularHolePatternto_have_circular_hole_patternAssertionYes
toHaveChamferFeatureto_have_chamfer_featureAssertionYes
toHaveFilletFeatureto_have_fillet_featureAssertionYes
toHaveMinimumWallThicknessto_have_minimum_wall_thicknessAssertionYes
toHaveVoidContinuityto_have_void_continuityAssertionYes
analyzeBrepanalyzeBrepQueryYes
analyzeMeshanalyzeMeshQueryNo
inspectGeometryinspectGeometryQueryYes
analyzeMeshOverlapanalyzeMeshOverlapQueryYes
toSatisfyRationalPlateto_satisfy_rational_plateContractNo
toSatisfyParallelPlaneDistanceto_satisfy_parallel_plane_distanceContractYes
queryPmiqueryPmiQueryNo
minimumDistanceminimumDistanceQueryYes

How to read a section

Every section has the same five parts; its signature and examples show one language at a time:

  • Signature: the matcher call and the type of its argument; in Python, the keyword fields.
  • Fields: each field, its type, its default and what it means.
  • Admitted geometry: which subjects the engine measures, and what it refuses.
  • Refusal codes: the diagnostic codes of a refused result, and the code of a failed one.
  • Examples: one call that passes and one the engine refuses. Each comment records the status the published packages returned.

How a matcher runs

expectGeo(subject) starts a chain, and each matcher call on it is one claim. The chain names the capability, keeps the fields as written, fills in the defaults the section lists, and sends the claim to the engine with the subject that loadModel admitted. The engine measures what the claim needs, from exact BRep evidence on a STEP subject or from triangles on a mesh, and answers with one status: passed, failed with the section's failure code, or refused with the reason it could not decide.

A passed claim returns its report; a failed or refused claim throws GeoSpecAssertionError in TypeScript and raises it in Python. .not (.not_ in Python) flips the polarity before the engine evaluates, so a refusal stays a refusal. The report keeps the canonical bytes of the claim and the result, so a run on another machine can compare digests. The API reference covers the calls; How it works covers the evidence.

Subjects in the examples

Each page opens with the block its examples run in:

import { readFile } from 'node:fs/promises';
import { expectGeo } from 'geospec';
import { createModelLoader } from 'geospec/model';
import { Engine } from 'geospec-engine/node';

const loadModel = createModelLoader({
  engine: new Engine(),
  readSource: async (source) => new Uint8Array(await readFile(source as string)),
});
const plate = await loadModel({ source: 'plate-with-through-bore.step', format: 'step' });
from geospec import GeoSpecEngine, expect_geo, load_model

with GeoSpecEngine(model_root="."):
    plate = load_model(file="plate-with-through-bore.step", format="step")

plate (plate-with-through-bore.step, a 40 × 40 × 20 mm STEP plate with a 10 mm through bore), box (box-10x20x30.step) and gear (involute-gear.glb, a spur gear mesh 19 mm across and 5 mm thick) are the site's demo models. Every other subject is a fixture from the engine repository, named by its path under packages/geospec-engine/ on the page that uses it. Where only Python reaches a verdict, such as a subject admitted in a y-up frame, the Python block admits it through engine.ingest_subject and the TypeScript example says so.

Python spells each matcher in snake_case (to_have_bounding_box) and keeps the camelCase field names as keywords (toleranceMm=); nested fields keep their names in both languages.

Shared field rules

  • Units. Lengths are millimetres, areas mm², volumes mm³, in the z-up frame the subject was admitted in.
  • Tolerance. Where a section lists tolerance, equality is abs(measured - expected) <= tolerance. The default is 0.02 mm unless the section says otherwise.
  • Numeric expectation. A number, or an object with any of value, greaterThan, greaterThanOrEqual, lessThan and lessThanOrEqual. Tolerance applies to value only; the four comparisons are strict as written. The object replaces the number in place: value: { greaterThanOrEqual: 2 }, and size: { x: { lessThan: 41 } } for an axis.
  • Points. A [x, y, z] triple, or an object with any of x, y and z to constrain only those axes.
  • Selectors. A component or occurrence name is an exact string or a regular expression: a RegExp in TypeScript, GeoSpecRegex(pattern, flags) in Python, because a compiled re.Pattern is refused with TypeError.
  • Malformed expectations. A claim with an unknown or malformed field refuses with GEOSPEC_INVALID_EXPECTATION, and the plan's other claims still run. details name the field and, when that key occurs once, its path, such as $.expected.size.w. A negated query, an unadmitted subject or an out-of-range budget still rejects the whole plan: TypeScript throws ProtocolError with code invalid-claim; Python raises GeoSpecAssertionError with that code.

Common refusals

These apply to every section, so the sections do not repeat them:

  • MATCHER_TIMEOUT: the claim used up its work-unit budget and was abandoned. The engine's default is 8,000,000 work units; raise it with workUnitLimit on expectGeo or loadModel, or with work_unit_budget on GeoSpecEngine.
  • GEOSPEC_ANALYSIS_LIMIT: the analysis the claim needs exceeds an analysis limit. The message names both quantities, Watertight scratch needs 65.5 KiB (67076 bytes); the analysis limit is 64 KiB (65536 bytes)., and details carry limitClass, unit, limit and required. The limit is the engine's maxMeshBytes or maxMeshEntries, which the host raises when it constructs the engine; a query limit, maxRecords or maxOutputBytes on queryPmi, which the caller raises in the query payload; or a capacity fixed by a proof profile, which no host limit raises. The suggestion says which.
  • GEOSPEC_RESOURCE_LIMIT: evidence the engine derives for the claim, such as a STEP subject's tessellation or its occurrence list, exceeds an admission limit: maxVertices, maxTriangles, maxOccurrences or maxSubjectBytes, with the same details. A subject over a limit at admission is a ProtocolError with the same numbers; the API reference lists the limits and Set tolerances and budgets shows a run.
  • GEOSPEC_UNSUPPORTED_EVIDENCE on a capability that reads faces, when the STEP subject's faces carry no surface (tessellated-only product geometry), and on a STEP subject admitted in a y-up frame, which answers minimumDistance only. Where a proof names the domain condition that failed, the refusal carries it as details.applicability.condition, a stable id such as retained-step-source. The code means an evidence gap, never a limit.
  • GEOSPEC_BACKEND_FAILED: the geometry backend could not complete the measurement.

A refusal is never a pass, and negating a claim does not turn a refusal into a pass. Read a refusal covers what to change.

On this page