Skip to content
프로젝트

pzfreo/quiddity has 83 GitHub stars and 10 forks. Star changes are not measured yet. Last checked 2026-11-11 04:06 UTC. Last push 2026-11-11.

이 수치를 측정하는 방법

Deterministic feature recognition for B-Rep geometry in STEP files written in Rust with Python bindings

측정된 스타 증가

in 24h
업데이트 지연
in 7 days
업데이트 지연
in 15 days
업데이트 지연
in 1 month
업데이트 지연

서로 겹치는 기간의 순증가량이며 일별 합계가 아닙니다. 측정값이 없으면 비워 둡니다. 스타는 관심도를 나타내며 품질을 보장하지 않습니다.

README.md

Original

quiddity

Find the manufacturing features in a STEP model: holes, pockets, slots, bosses, steps, fillets, patterns, springs and turned profiles, with their measured sizes and positions. quiddity also matches the features of two revisions of a part, and reads and writes AP242 PMI (dimensions, tolerances, datums, notes and their callouts).

It works from the B-rep geometry alone, with no CAD system, feature tree or OpenCascade. It is pure Rust, and the same input always gives the same output. It is available as a command line, a Rust library and a Python package.

Automatically recognised features of NIST CTC-01: two views, each face coloured by the feature quiddity recognises it as: holes, slots, notches, V-channels, the hexagonal boss, chamfers and fillets

Each face of NIST CTC-01 (AP242) coloured by the feature it belongs to; grey faces belong to no feature shown here.

Status: 0.4.9 (2026-11-07). See CHANGELOG.md.

The geometric validation accuracy tool compares exact volume, area and centroid against STEP validation properties and independent OCCT measurements.

Install

Command line uv tool install quiddity (or pipx install quiddity): the Python package's quiddity command, with no Rust toolchain needed; upgrade with uv tool upgrade quiddity. Or cargo install quiddity.
Rust library quiddity = "0.4" in [dependencies] (the geometry is the haecceity crate, a B-rep reader and query library)
Python 3.11+ pip install quiddity (an abi3 wheel with no Python dependencies; see Python)

Every release is published to PyPI and crates.io, so uv tool, pipx, pip, cargo install and quiddity = "0.4" all get the latest one.

Cargo features: cli (the command line) and presentation (drawing PMI callouts) are on by default. A library build that does not want clap (WASM, say) can use default-features = false, features = ["presentation"]. manifest enables the range-based assembly APIs and is included by cli. Off by default:

  • json-import: the versioned PMI JSON interchange (pmi json … commands).
  • f3d: Autodesk Fusion .f3d input (visible solid geometry only, no PMI; see Fusion input).

Read large assemblies one product at a time with quiddity manifest and quiddity recognise --manifest; see assembly manifests for range checks, placements, fallback and Python APIs.

Quick start

quiddity part.step                      # the part's features, as JSON
quiddity correspond old.step new.step   # what changed between two revisions
quiddity pmi read part.step             # the file's PMI, as JSON
import json, quiddity

document = json.loads(quiddity.recognise("part.step"))["document"]
for feature in document["records"]:
    print(feature["family"], feature["parameters"], feature["faces"])
let part = quiddity::read_step_file(std::path::Path::new("part.step"))?;
let recognised = quiddity::correspondence::recognise(&part);
let document = quiddity::recognition::document(&recognised, part.faces.len());

for record in document.records.iter().filter(|r| r.family == "holes") {
    let p = &record.parameters;
    println!("{}: Ø{} × {} on faces {:?}", record.id, p["diameter"], p["depth"], record.faces);
}

Recognise a part

For a part with a counterbored hole, quiddity part.step includes:

{
  "id": "holes/0",
  "family": "holes",
  "faces": [6, 8],
  "parameters": {
    "diameter": 8.0, "depth": 14.0, "bottom": "through",
    "cbore": { "diameter": 16.0, "depth": 6.0 },
    "axis": [0.0, 0.0, -1.0], "location": [-22.0, 0.0, 10.0]
  },
  "evidence_status": "verified"
}

That record is one entry of the output's document, the versioned form to build on (quiddity-rust/recognition/6; the identifier keeps its original name):

  • records: one entry per feature. Each gives its family, the STEP faces it is made of, its measured parameters, and whether its evidence is verified or unproved.
  • face_accounting: what every face of the part is: part of a feature, part of the body (with the reason), or refused or unexplained.
  • source_sha256: the input file's hash.

Every coordinate and direction is in the file's own coordinates. quiddity finds the part's natural orientation itself, so a part rotated in its file is recognised the same way.

What each field means: schema 6, face accounting, and the trust contract, which says what verified does and doesn't promise.

Families

Kind Families
Holes holes (through, blind, counterbored, countersunk, spotfaced), countersinks, hole_patterns, double_d_bores, modelled_threads
Pockets and slots pockets, prismatic_pockets, edge_open_circular_pockets, edge_open_prismatic_recesses, pocket_patterns, slots, rectangular_blind_slots, round_bottom_blind_slots, semicircular_blind_slots, slot_patterns, rectangular_through_notches
Channels and grooves channels, v_channels, grooves, annular_grooves, face_grooves
Steps and levels through_steps, angled_steps, oblique_through_steps, paired_ramp_steps, circular_blind_steps, step_levels, risers
Raised features bosses, polygonal_bosses, pads, gusset_ribs, gusset_rib_patterns
Edges fillets, blends, chamfers
Turned parts turned_bodies, turned_steps, repeating_radial_profiles, circular_face_patterns
Springs helical_springs
Body plates, polygonal_stock, sheet_metal_bodies, thin_wall_bodies, flats, interior_voids, cylindrical_profiles, freeform_surfaces
Sections section_passages, section_recesses

Compare two revisions

quiddity correspond old.step new.step says what happened to each feature between two revisions: carried (unchanged), adapted (with what changed), orphaned (gone in the new revision) or ambiguous (more than one candidate, so none is guessed), and which features are new. It works when the part is moved or re-modelled, because it matches revision-independent fingerprints rather than face numbers. If a hole moves:

{ "old": "holes/2", "new": "holes/2", "class": "adapted",
  "changes": { "position": { "old": [40.0, 45.0, 5.0], "new": [25.0, 45.0, 5.0] } } }

Either side can also be saved recognition JSON. In Rust, use quiddity::correspond(&old.fingerprints, &new.fingerprints). See correspondence.

Read and write PMI

quiddity reads semantic AP242 PMI and writes it back into the same file. PMI JSON is bound to the exact STEP text it was read from; a write keeps everything else in the file, and checks the result by reading it back before replacing the destination.

  • Modes: replace re-authors the part's PMI; add adds to it and keeps every existing entity byte for byte (it refuses, naming the entities, if that isn't possible); remove takes PMI out.
  • Callouts: the writer draws the visible callouts (frames, dimensions, datums, notes) in tessellated strokes. It lays them out itself, or uses the positions a source supplies (--source-presentation, Python presentation=), drawing only what the source didn't place.
  • Practice: the writer follows the CAx-IF PMI Recommended Practice, and the reader reports where a file departs from it. See AP242 practice.
quiddity pmi read part.step [--part N] > part.pmi.json
quiddity pmi check part.step part.pmi.json
quiddity pmi write part.step part.pmi.json -o out.step [--mode add|replace|remove]

With --features json-import, the versioned interchange (reference) is also available, for producers such as XCAF converters:

quiddity pmi json export part.step > part.pmi.json
quiddity pmi json validate part.pmi.json
quiddity pmi json import part.step part.pmi.json -o written.step [--source-presentation callouts.json]
quiddity pmi json presentation part.step > part.presentation.json

The schemas ship in haecceity's schema/ directory. From Python, quiddity.pmi does the same in process (pmi.validate, pmi.write); see Python.

Command line

quiddity <file.step>                                  recognise the part's features
quiddity correspond <old.json|old.step> <new.json|new.step>   match features across revisions
quiddity evidence <file.step> [--framed]              the recognition evidence for each feature
quiddity fingerprints <file.step>                     the features' fingerprints
quiddity capabilities                                 this build's versioned capabilities
quiddity parts <file.step>                            list an assembly's parts
quiddity manifest <file.step> -o <manifest.json>       scan product ranges
quiddity recognise <file.step> --manifest <manifest.json> --out-dir <dir> [--parts p0,p7]
                                                       recognise products and write results
quiddity pmi read <file.step> [--part N]              the file's PMI as JSON
quiddity pmi check <file.step> <pmi.json>             validate a PMI document against the part
quiddity pmi write <file.step> <pmi.json> -o <out.step> [--mode add|replace|remove]
                   [--presentation refuse|remove]     write PMI into the file
quiddity brep <file.step> -o <out.step> [--pmi <pmi.json>]   the B-rep and PMI as a new AP242 file
quiddity serve                                        JSON-lines requests on stdin
quiddity completions <SHELL>                          a shell completion script
quiddity --help

quiddity <command> --help gives a command's arguments.

Recognition and inspection commands print JSON; manifest and recognise --manifest write their requested files. completions, help and version print text. STEP inputs may be .step, .stp or gzipped; manifest product reads require an uncompressed source. The exit code is 0 for success, 1 for an unreadable file or a refused operation, and 2 for wrong usage.

quiddity serve keeps one process open for applications: one JSON request per line on stdin, one response line per request on stdout, e.g. {"id":1,"op":"recognise","step":"part.step"}. The operations are recognise and correspond.

Shell completion. quiddity completions SHELL prints a completion script for bash, zsh, fish, powershell or elvish:

mkdir -p ~/.local/share/bash-completion/completions && quiddity completions bash > ~/.local/share/bash-completion/completions/quiddity
mkdir -p ~/.zfunc && quiddity completions zsh > ~/.zfunc/_quiddity
# zsh: add `fpath=(~/.zfunc $fpath)` before `compinit` in ~/.zshrc, then restart zsh
mkdir -p ~/.config/fish/completions && quiddity completions fish > ~/.config/fish/completions/quiddity.fish

Limits

  • quiddity reports what it can prove from the geometry. A file that reads without errors isn't a promise that every feature was found: check face_accounting for faces left unexplained.
  • Malformed solids, approximate boundaries and unsupported surfaces can give refusals or unproved records. Refusals are records too, so nothing is silently dropped.
  • Known wrong results are listed, with evidence, in known defects.
  • How the STEP reader heals input to match OpenCascade: notes.

Packages

Package What it is
quiddity (crate) recognition, fingerprints, correspondence, the PMI JSON and the command line
haecceity (crate, crates/haecceity) the geometry: STEP reading, the B-rep, measurement and queries, and semantic PMI reading and writing (it does not model; see its README); re-exported as quiddity::kernel
quiddity (Python, crates/quiddity-py) the Python wheel over both

Contributing

See CONTRIBUTING.md, and docs/development.md for how the test suite and regression snapshots work. Contributions are taken under Apache-2.0, with each commit signed off (git commit -s) under the Developer Certificate of Origin.

History

This repository was called quiddity-rust until 2026-11-03; identifiers such as quiddity-rust/recognition/6 keep that name. It began as a port of the Python quiddity library (now pzfreo/quiddity-python), which it no longer depends on; the archived comparison is in docs/history.

관련 프로젝트 살펴보기