GeoSpec
engine 0.4.0

Query geometry

Ask the engine what it measured and read the report without asserting anything.

Open Markdown

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. createGeoSpecAssertionClient({ engine }) from geospec/assertion-client gives client.query({ capability, subject, payload }), and its subjects come from createGeoSpecNativeModelLoader in geospec/runner/native 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
check.ts
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();

The engine loads in this tab when you run the spec.

Select a claim to see what it checks.

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.result["status"], report.result["evidence"] 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.2862601528904634e-13, 5.731384959986079e-17, 10], "diameter": 10, "through": true }.

3. Choose a query

QueryReadsOn a mesh
analyzeBrepThe exact BRep inventory of a STEP subject.refused, GEOSPEC_BREP_EVIDENCE_UNAVAILABLE.
analyzeMeshThe 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.
inspectGeometryWhat each selector matched.body selectors only; an axis or face selector answers refused, GEOSPEC_SELECTOR_UNSUPPORTED_EVIDENCE.
analyzeMeshOverlapThe shared volume of each pair of named components.Two or more named parts; a single body answers refused, GEOSPEC_COMPONENT_PARTITION_INCONCLUSIVE.
queryPmiThe product manufacturing information records of a STEP file; the plate's inventory has "status": "empty".refused, GEOSPEC_UNSUPPORTED_EVIDENCE.
minimumDistanceThe 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_SELECTOR_UNMATCHED, 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.

On this page