Skip to content

openbim-ifcx ​

Lossless reader and writer for IFC5 / IFCX files, the layered JSON model.

Crateopenbim-ifcx 0.1.1 on main
Latest release0.1.1 (2026-10-03)
Distributed ascrates.io openbim-ifcx
Installcargo add openbim-ifcx
RequiresRust 1.88.0
LicenseMIT
API documentationrustdoc · docs.rs
Sourcecrates/openbim-ifcx/

About ​

From the crate's README.md:

OpenBIM.rs crate for IFC5 / IFCX. It reads and writes ifcx_alpha files losslessly, composes layered nodes into a resolved tree as upstream does (flatten, then compose), and checks attribute values against the file's schemas, collecting every failure with its node path, attribute id, and JSON pointer (IfcxFile::validate, validate_flat, validate_attributes). It resolves imports into an ordered layer stack through a caller-supplied resolver (LayerStackBuilder::build for one main layer, build_all for several layers stacked as upstream's ifcx compose does), validates the stack against the schemas of all its layers (LayerStack::validate), and federates schemas and data with every layer after the layers it imports, so a layer overrides its imports (buildingSMART/IFC5-development#144). flatten_owned and LayerStack::into_federated move nodes and attribute values instead of copying them, which makes flattening large models several times faster than flatten over borrowed nodes. The composed tree shares sub-trees between instances instead of copying them, and reference cycles and unknown references are typed errors.

Features:

  • integrity (default): check SRI-style sha256-<base64> (also sha384, sha512) integrity values on imports, using sha2 and base64. Without it, imports that carry integrity are rejected.
  • fs: FsResolver, which loads imports from local files. The crate never uses the network.

See the repository capabilities, the documentation with a Rust guide, and the viewer, which shows an IFCX file in the browser.

Licensed under MIT.

Public API ​

The crate root, as rustdoc shows it. Follow a name to its rustdoc entry.

ModuleSummary
composeLayer composition, following upstream src/ifcx-core/composition of buildingSMART/IFC5-development for the ifcx_alpha draft.
layersLayer stacks: loading a main layer and, recursively, its imports.
validateChecking attribute values against a file's schemas.
ItemKindSummary
ArrayRestrictionsstruct
composefunctionComposes flattened nodes into a tree, as upstream's LoadIfcxFile does after flattening.
ComposedNodestructOne node of the composed tree. Upstream calls this a post-composition node.
ComposeErrorenumWhy flattened nodes could not be composed.
CompositionstructThe composed tree of a set of flattened nodes.
DataTypeenumThe dataType of a value description. Names this crate does not know read as DataType::Other and are written back unchanged.
EnumRestrictionsstruct
Extratype aliasFields this crate does not model, kept in input order for round trip.
FailureKindenumWhat is wrong with one attribute value.
FlatNodestructAll opinions about one path, merged in layer order.
flattenfunctionMerges input nodes into one FlatNode per path.
flatten_ownedfunctionflatten for nodes the caller no longer needs: the nodes are consumed and their paths, maps, and attribute values move into the result instead of being copied.
IfcxFilestructOne IFCX file: a single layer of a dataset.
IfcxHeaderstruct
IfcxNodestructOne node opinion. children and inherits map a local name to a referenced path; a None value deletes that entry when layers merge.
IfcxSchemastructDescribes the values allowed for one attribute id.
IfcxValueDescriptionstruct
ImportNodestructA reference to another IFCX file that this layer builds on.
INTERNAL_ATTRIBUTE_PREFIXconstantAttribute ids with this prefix are not validated, as upstream.
JsonTypeenumThe JSON type of a value, for failure messages.
ObjectRestrictionsstruct
ReadErrorstructA file that could not be read, with the 1-based location of the problem.
ReadErrorKindenumWhy a file could not be read.
validate_attributesfunctionChecks the attributes of nodes, given as (path, attributes) pairs, against schemas and collects every failure.
validate_flatfunctionChecks flattened nodes, as flatten or flatten_owned return them, against schemas. This is what upstream validates: one merged node per path, in the flattened order.
validate_nodesfunctionChecks the attributes of each node as it is, without merging nodes that share a path. Nodes without attributes are skipped.
ValidationFailurestructOne attribute value that does not match its schema.
ValidationReportstructEvery failure found in one validation run, in node and attribute order.
WriteErrorstructA file that could not be written.

Cargo features ​

FeatureDefaultEnables
fs—
integrityyesdep:base64, dep:sha2

Examples ​

  • compose-json: cargo run -p openbim-ifcx --example compose-json

Within the workspace ​

Changes ​

Unreleased, on main:

Changed ​

  • Breaking: a layer now overrides the layers it imports, as agreed upstream in buildingSMART/IFC5-development#144 (2026-10-05): "imported data should come 'before' the main data". LayerStackBuilder returns the layers in federation order: every layer after its own imports, recursively; sibling imports in written order, so a later import overrides an earlier one; each layer once, where it is first reached; the main layer last. main → [a, b], a → [c] now gives c, a, b, main (was main, a, c, b), and main → a → b gives b, a, main (was main, a, b). Code relying on the old order, in which an import overrode its importer and the main layer had the lowest priority, now composes and validates differently whenever an import carries data or redefines a schema. Upstream's code at 1a63082 still uses the old order until a pending upstream pull request lands (#36).
  • Breaking: LayerStack::layers, keys and into_layers return the federation order, so the main layer is last, not first; LayerStack::main still returns the main layer. For build_all, main is now the last layer of the stack, the strongest named one (was the first named one), and the federated header is its header (#36).
  • Breaking: federate and federate_owned take the header of the last file, the strongest, instead of the first; schemas and data are merged as before. LayerStack::federate and into_federated thus keep the main layer's header (#36).
  • LayerStackBuilder::allow_cycles(true) skips the import that closes a cycle, as before; under the new order the layer that import names comes after its importer, and the main layer stays last (main → a → main gives a, main) (#36).
  • LayerStackBuilder walks imports without recursion, so a long import chain cannot overflow the stack. integrity is still checked on every import edge (#36).

Latest release, 0.1.1 (2026-10-03):

No breaking change: every addition below is new API, and existing functions and types keep their signatures.

Added ​

  • LayerStack::validate checks a layer stack built with its imports: the schemas of every layer, merged as federate does, against the attributes of every layer, merged per path as flatten does. An attribute whose schema lives only in an imported file now validates. validate_flat checks the output of flatten or flatten_owned (#42).
  • LayerStackBuilder::build_all stacks several layers, weakest first, as the imports of a main layer without data, as upstream's ifcx compose does (#42).
  • flatten_owned, FlatNode::merge_owned, federate_owned, and LayerStack::into_federated consume their input and move nodes and attribute values instead of copying them. In the opt-in upstream_composition test (release build) flattening Tekla House drops from 88 ms to 18 ms and Railway_project_IFC5 from 60 ms to 8 ms (#43).

Changed ​

  • IfcxFile::validate merges attributes per path by reference instead of copying every value; the report is unchanged (#43).

Migration ​

  • To flatten without copying, replace flatten(&file.data) with flatten_owned(file.data) where the nodes are not needed afterwards, and stack.federate() with stack.into_federated(). flatten over borrowed nodes still copies each attribute value, as before.
  • To validate a file with its imports, build its layer stack and call stack.validate() instead of file.validate().

Fixed ​

  • IfcxFile::validate and validate_attributes walk schema inherits with an explicit stack and check each inherited schema once per value. A long inheritance chain overflowed the stack, and diamond-shaped inheritance doubled the work per level (22 levels took seconds and reported one failure four million times); a schema reached along several paths now reports its failures once. Found while fuzzing (#41).

Full history: crates/openbim-ifcx/CHANGELOG.md, and every release of every crate on the project changelog.

Released under the MIT licence. No buildingSMART files or texts are published here.