Query geometry
Ask the engine what it measured and read the report without asserting anything.
A query reports a measurement instead of comparing it with an expectation, and it never throws: a refused query is a report with a diagnostic. Read status first; only passed carries a measurement.
Queries run on the assertion client. create from geospec/ gives client.query({ capability, subject, payload }), and its subjects come from create in geospec/ rather than the loader in geospec/model, which admits models for chains only. The demo's check.ts shows the setup.
query_geo(subject, capability, payload) from geospec takes the model load_model returns, with the payload as a dict.
1. Query the plate
const part = await loadModel({ source: 'plate-with-through-bore.step', format: 'step' });Tab indents. Press Escape, then Tab, to leave the editor.
The spec as a file, with the model loaded over the native addon
import { readFile } from 'node:fs/promises';import { createGeoSpecAssertionClient } from 'geospec/assertion-client';import { createGeoSpecNativeModelLoader } from 'geospec/runner/native';import { Engine } from 'geospec-engine/node';const engine = new Engine();const loadModel = createGeoSpecNativeModelLoader({ engine, readSource: async (source) => new Uint8Array(await readFile(source as string)) });const client = createGeoSpecAssertionClient({ engine });const part = await loadModel({ source: 'plate-with-through-bore.step', format: 'step' });await client.query({ capability: 'analyzeBrep', subject: part,});await client.query({ capability: 'inspectGeometry', subject: part, payload: { selectors: [{ kind: 'axis', query: { axis: { direction: [0, 0, 1] }, }, }], },});await loadModel.releaseAll();engine.close();plate-with-through-bore.step · 19 KB · copied from an engine test fixture
Run the spec to see what the engine answers for each claim. Then change an expected value and run it again.
analyzeBrep takes only the subject and reports the whole BRep inventory. inspectGeometry resolves selectors and reports what each one matched; this one asks for the axis along z, which is the bore. Change the selector to { kind: 'face', query: { surfaceType: 'plane' }, expect: 'many' } and the report lists the plate's six planar faces with their normals and offsets.
2. Read a report
A query answers passed with its measurement in the evidence, or refused when the evidence it reads is missing or cannot decide, with a diagnostic naming the reason. It asserts nothing, so it never answers failed.
Read report.status, report.evidence and report.diagnostics.
Read report., report. and report.diagnostics; report.passed is the status as a boolean.
The bore selector reports:
{
"bounds": { "max": [5.0000001, 5.0000001, 20.0000001], "min": [-5.0000001, -5.0000001, -1e-7] },
"center": [3.2862601528904634e-13, 5.731384959986079e-17, 10],
"direction": [0, 0, 1],
"kind": "axis",
"name": "axis:whole#6",
"radius": 5,
"source": "selector"
}analyzeBrep reports under brep: boundingBox, circularHoles, circularHolePatterns, cylindricalFaces, planarFaces, chamferFeatures, filletFeatures, massProperties, topologyCounts, validity and the topology the feature claims qualify. The plate's one hole reads { "axis": "z", "axisRange": { "max": 20, "min": 0 }, "center": [.
3. Choose a query
| Query | Reads | On a mesh |
|---|---|---|
analyzeBrep | The exact BRep inventory of a STEP subject. | refused, GEOSPEC_. |
analyzeMesh | The triangles the engine measures: triangleCount, vertexCount, watertight, boundingBox and meshQuality with signedVolume, surfaceArea and per-triangle rows. | The mesh itself; a STEP subject answers with the engine's own tessellation. |
inspectGeometry | What each selector matched. | body selectors only; an axis or face selector answers refused, GEOSPEC_. |
analyzeMeshOverlap | The shared volume of each pair of named components. | Two or more named parts; a single body answers refused, GEOSPEC_. |
queryPmi | The product manufacturing information records of a STEP file; the plate's inventory has "status": "empty". | refused, GEOSPEC_. |
minimumDistance | The exact distance between two occurrences of an AP242 STEP assembly, a typed result in TypeScript and the report's fact in Python; see Compare parts. | refused, unsupported-evidence. |
A selector for inspectGeometry is an occurrence path string such as 'subject', or an object: { kind: 'occurrence', name } takes a name or a regular expression, and body, face, axis and plane take a query such as { surfaceType: 'cylinder' } or { normal: { direction: [0, 0, 1] } }. expect: 'many' allows more than one match; a selector that matches nothing refuses the query with GEOSPEC_, and the report lists no matches.
Variations
No negation. A query states no expectation, so there is nothing to negate: client.query has no .not and query_geo no not_.
A query is not a claim. A report is a measurement to read, not a pass to count. When a spec needs the value to hold, write the matching claim, such as toHaveCircularHole from Find holes and features, so a wrong value fails.
Budgets and the reference. A query charges work units like a claim; Set tolerances and budgets covers the accounting, and the queries reference lists every field.
Compare parts
Select two parts of an assembly by name, claim their clearance or non-interference, and query the exact distance between them.
Set tolerances and budgets
State how close a measurement must come, compare with strict bounds, and set the work and the memory a claim may spend before it is refused.