Capabilities and status
This page is deliberately conservative. It exists so that an engineer — or a coding agent — can scope work against what the code does, not against what the IFC schema contains or a crate name suggests.
Status vocabulary
| Term | Meaning |
|---|---|
| Implemented | Executable behaviour with tests. Safe to build on. |
| Partial | A real vertical slice exists; the issues in its row name what it lacks, and unsupported input returns a typed error. |
| Scaffold | The crate exists and its ownership is settled. No behaviour. |
| Absent | Not present in the workspace at all. |
No source file reserves a name for later work: a module that holds only comments fails the gate, and planned work is an issue (ADR 0019). A module path in the tree is therefore always backed by code.
Workspace census
Generated by cargo run -p xtask -- docs from each crate's [package.metadata.openbim]: status is a declared judgement, and gaps lists the open issues behind it. A Partial crate must name at least one. scripts/gate.sh fails if the table drifts from the manifests. Crate size is deliberately not published here: it changes with nearly every commit, and a committed figure that moves that often only produces merge conflicts. Coverage measures what each crate does instead.
| Crate | Status | Open gaps |
|---|---|---|
ifc-alignment | Implemented | |
ifc-approval | Implemented | |
ifc-author | Implemented | |
ifc-classification | Implemented | |
ifc-constraint | Implemented | |
ifc-control | Implemented | |
ifc-cost | Implemented | |
ifc-element-type | Implemented | |
ifc-geometry | Partial | #311 |
ifc-georef | Implemented | |
ifc-material | Implemented | |
ifc-model | Implemented | #105 |
ifc-occurrence | Implemented | |
ifc-properties | Implemented | |
ifc-resource | Implemented | |
ifc-schedule | Implemented | |
ifc-schema | Implemented | |
ifc-spatial | Implemented | |
ifc-step | Implemented | |
ifc-structural | Implemented | |
ifc-style | Implemented | |
ifc-systems | Implemented | |
ifc-tabular | Implemented | |
ifc-template-catalog | Implemented | |
ifc-validate | Implemented | |
ifc-xml | Implemented | |
openbim-ifc | Implemented | |
openbim-ifc-binding-core | Implemented | |
openbim-ifc-capi | Implemented | |
openbim-ifc-cli | Partial | #329 |
openbim-ifc-dotnet | Implemented | |
openbim-ifc-py | Implemented | |
openbim-ifc-wasm | Implemented |
Geometry items this repository does not address
Every concrete IfcRepresentationItem subtype in IFC4 ADD2 TC1 and IFC4X3 ADD2 is named somewhere in this repository -- implemented, refused, or explicitly classified as carrying no shape. This section is generated by walking down from the schema, so it reports zero only when the walk actually finds nothing unaddressed. Being named is not the same as being implemented: see the tables above for the status of each one.
0 of 33 crates are scaffolds.
Core: model, codecs, schema
| Capability | Status | Evidence |
|---|---|---|
| Entity graph with positional attributes | Implemented | ifc-model::Model |
| Round-trip of entities the build does not understand | Implemented | crates/openbim-ifc/tests/costing_roundtrip.rs (runs with no domain crate compiled) |
STEP (.ifc) read and write | Implemented | ifc-step; deterministic model order, finite scalar safeguards, generic syntax delegated to openbim-step |
| ifcXML read and write | Implemented | ifc-xml: its own lossless layout, read and written, typed from the schema when one is given (SchemaReading::Strict), under an exact release namespace with a strict profile (not valid against the XSD; an opt-in xmllint check pins the departures); the buildingSMART XSD configuration of IFC4 ADD2 TC1 and IFC4X3 ADD2, read and written (XmlCodec::xsd), its rules checked against both release XSDs and its IFC4 output validated against IFC4.xsd (opt-in xmllint check); content either layout cannot carry exactly is a typed error |
ifcZIP (.ifczip) read and write | Implemented | openbim-ifc feature zip (ifc::ifczip, IfcZipCodec; #450): one STEP or ifcXML model (either layout, detected from its content) at the archive root, per buildingSMART implementation agreement CV-2x3-154; Stored and Deflate only. No model, several, an unknown inner format, an encrypted entry and another compression method are typed refusals; decompression is bounded by an absolute and a ratio budget, checked while inflating. Writes one Deflate entry, reproducibly. Pure Rust (zip with flate2/miniz_oxide). crates/openbim-ifc/tests/ifczip.rs |
| IFC-JSON | Absent | Not planned (#122): buildingSMART's ifcJSON never became a standard; see ADR 0020 |
| IFC5 / IFCX | Absent | Out of scope here: a different data model, developed as its own family in openbimrs/ifcx (ADR 0020); the IFC5 schema token is refused with a typed error |
| EXPRESS schema metadata, subtype queries | Implemented | ifc-schema |
| GlobalId base-64 encode/decode | Implemented | ifc-model::guid |
| Entities by GlobalId; new GlobalIds | Implemented | openbim-ifc::GlobalIdIndex (built once; a duplicated GlobalId is refused with every holder, never answered with one) and by_guid; new_guid (random, RFC 9562 version 4, through getrandom; in the browser with js-random) and name_based_guid (reproducible, version 8). In every binding. crates/openbim-ifc/tests/object_relations.rs. |
| An object's type, a type's occurrences, openings and fillings | Implemented | openbim-ifc::{type_of, occurrences_of, openings_of, fillings_of, voided_element_of} read IfcRelDefinesByType, IfcRelVoidsElement and IfcRelFillsElement in IFC2X3, IFC4 and IFC4X3, refusing two answers where the schema allows one. In every binding. |
| Selector queries; values by path | Implemented | openbim-ifc::selector (feature selector, #464): a versioned grammar close to IfcOpenShell's selector (class, GlobalId, attribute, property, type, material, classification, location and group facets, patterns, , lists and + unions) parsed into a typed query with spanned errors, evaluated over the type, GlobalId, property and relationship indexes; values read and written by path through one checked transaction. In every binding and the select command. Guide; crates/openbim-ifc/tests/selector.rs. |
| Tables of values by path | Implemented | openbim-ifc::sheet (feature sheet, XLSX with sheet-xlsx, #474): selected entities exported by value paths (attributes, properties, quantities, relations) as CSV, TSV or XLSX keyed by GlobalId or id, and a table imported back as one checked transaction typed by each target's declared or stated type, with a planned diff, every refusal by row and column, and an unchanged table a no-op. In every binding and the export-table, import-table and edit commands. Guide; crates/openbim-ifc/tests/sheet.rs. |
| Spatial containment tree traversal | Implemented | ifc-spatial::SpatialTree; facade feature spatial. See below. |
| Element properties by spatial container | Implemented | openbim-ifc::spatial_properties (features spatial and properties): each container in tree order with its contained, aggregated-part and referenced elements, each with its exact property list or its own ExactPropertyError, in IFC2X3, IFC4 and IFC4X3. crates/openbim-ifc/tests/spatial_properties.rs. |
| Objectified relationship traversal | Implemented | All 45 concrete IfcRel* families are read, and IFC2X3's IfcRelAssignsTasks. Spatial composition, containment, coverings, space boundaries, element connection and interference, assignment, declaration and system service in ifc-spatial; association and definition in ifc-classification, ifc-material, ifc-properties, ifc-resource, ifc-approval and ifc-constraint; connectivity in ifc-systems and ifc-structural; sequencing and IFC2X3 task time assignment in ifc-schedule, sequencing in ifc-cost; feature attachment in the openbim-ifc reachability check. Slot positions are asserted against the shipped IFC2x3/IFC4/IFC4x3 schemas in crates/ifc-spatial/tests/slot_layout.rs, and crates/openbim-ifc/tests/relationship_census.rs fails if a family loses its reader. |
| Distribution systems, ports and connectivity | Implemented | ifc-systems reads systems and membership, ports through both IfcRelNests and the legacy IfcRelConnectsPortToElement, the connection network, flow roles and direction, zones with their WR1 membership rule, spatial containment vs referencing, and direction-aware upstream/downstream queries. Relationship-only: no geometry is read, so a geometry-free file still yields a full network. |
| Cost items, rates and rollups | Implemented | ifc-cost reads IfcCostItem nesting, IfcCostValue component trees with arithmetic operators, and totals a cost tree. Currencies are compared, never converted: a rollup mixing EUR and USD is refused. Typed drafts stage selected IFC4 values, items, schedules, nesting, and schedule assignments atomically. |
| Work schedules, tasks and sequencing | Implemented | ifc-schedule reads IfcWorkPlan/IfcWorkSchedule, IfcTask with IfcTaskTime, IfcRelSequence with signed lag, work calendars and events, and produces a deterministic execution order. Cycles report the offending path. |
| Transactional authoring | Implemented | ifc-model::Transaction stages structural edits, validates them against the projected end state, and applies them as a unit. A removal that would orphan a surviving reference is refused, as is a commit against a model whose revision moved since the transaction opened. ifc-model remains schema-agnostic; typed staging helpers live in domain crates, including classification, documents, libraries, materials, quantities, cost, style, structural, and resources. |
| Undo and redo | Partial | ifc-model::Inverse records the exact inverse of a change (attributes, created and removed entities, file and type-index order, header, next free id), and History keeps a bounded undo and redo stack; History::track wraps an authoring batch or any other change as one entry. Applying an inverse writes the same STEP bytes. The language bindings do not expose it yet. |
| Quantity authoring | Implemented | ifc-properties stages quantity writes onto a caller-owned transaction, so a takeoff spanning many elements lands atomically. The declared measure type is preserved on every write. |
| Schema validation | Implemented | ifc-validate checks references, required slots, aggregate shape, bounds and element uniqueness, UNIQUE clauses, entity types, abstract instantiation, scalar forms and STRING(n) FIXED widths against the exact schema the file declares (IFC2x3 TC1, IFC4 ADD2 TC1, or IFC4X3 ADD2). Registered rules run under a hard findings-storage cap; the coverage page lists each one and whether it is evaluated. They include external-reference identity, sequence endpoints, decomposition and assignment self-reference, material and path-connection priority bounds, and space-boundary physicality across all three concrete IfcRelSpaceBoundary subtypes. A registered rule that applies to an instance but cannot be decided for it (an operand of a shape it cannot read, a missing target, or an attribute the tables lack) is reported as an evaluation error and makes the report non-conformant, never skipped. Given the release's own .exp text (CC BY-ND 4.0, so supplied at run time, never bundled), ifc_validate::express evaluates every entity WHERE rule, type WHERE rule, global rule and function of IFC2X3, IFC4, IFC4X1, IFC4X2 and IFC4X3 under three-valued logic and step and depth budgets, and checks INVERSE cardinality; UNKNOWN results are reported as indeterminate. On the fixture corpus and IfcOpenShell's own rule fixtures its verdicts match IfcOpenShell's express_rules except where the coverage page lists why. With the PSD/QTO catalog, a Pset_/Qto_ set the release's catalog does not define is a warning, and so are a property or quantity inside a defined set that its template does not declare and a set kind, entity form or value type that differs from it (bSI PSE001). Without the rule text, rules not hand-written are reported as unsupported; a clean report never implies full EXPRESS conformance. The CLI (validate --express FILE.exp) and the JavaScript, Python, C and .NET bindings evaluate the same rules from .exp text the caller supplies. |
| Property sets and every property value family | Implemented | ifc-properties reads single, enumerated, bounded, list, table, reference and complex properties. The declared measure type (IfcLengthMeasure and friends) is retained, because it is the only statement of what a bare number means. |
| Occurrence/type property precedence | Implemented | An occurrence property set overrides a same-named set inherited from the object's type. The shadowed type set is kept, so a checker can explain why an effective value differs from the type default. |
| Quantities and unit resolution | Implemented | Simple and complex quantities, SI prefixes carried as exact decimal exponents, conversion-based and derived units. WR21 (unit matches quantity kind) and WR22 (non-negative value) breaches are reported. ifcopenshell.validate checks both only when its EXPRESS rules are enabled (express_rules=True, --rules), not in its default run. Quantities are read as authored assertions and never computed from geometry. |
| Unit conversion and a model's length unit | Implemented | ifc-properties::unit_conversion converts between any two units of the same dimensions (SI with prefixes by exact powers of ten, conversion-based units through their factors, derived units by their exponents, IFC4 Table 673 named units with exact factors) and refuses others, monetary and context-dependent units, and offset units pending #110; format_length writes decimal or feet-and-inches text. openbim-ifc::convert_length_unit rescales every length, area and volume value of a model to a new length unit as one transaction, the lengths identified by the release's measure types, parameter values by their curve's or surface's parameter space, map coordinates by their MapUnit, and refuses by name what it cannot carry. In every binding and the CLI (convert-units). IFC2X3, IFC4, IFC4X3: crates/openbim-ifc/tests/length_unit_corpus.rs, length_unit_cases.rs. |
Type index (ids_of_type, of_type) | Implemented | Model::ids_of_type, Model::of_type, Model::type_histogram |
| Reverse-reference index ("who references me") | Implemented | ifc-model::ReverseIndex, built on demand; records the attribute slot |
| Bounded graph traversal with cycle reports | Implemented | ifc-model::{depth_first, breadth_first, find_cycle} with Budget/Stop |
| Dangling-reference detection | Implemented | Model::dangling_references |
| Schema-checked entity construction (authoring) | Implemented | ifc-author::EntityBuilder; facade feature author. See below. |
| Delete a product with its owned data; purge orphans | Implemented | openbim-ifc::AuthorOp::RemoveProduct removes a product or type object with what it solely owns (placement, representation, own property sets, material usage, openings, ports, relationships left without an end), decided by reference counts within the batch's one transaction, and reports what it kept as shared and why; dependent placements are refused or re-based with the composed transform, a type with occurrences refused or untyped. AuthorOp::Purge removes resource entities no IfcRoot reaches, or unreferenced entities of named classes; staging the batch is the dry run. In every binding (remove_product, purge); the raw binding remove is deprecated. IFC2X3, IFC4, IFC4X3: crates/openbim-ifc/tests/cascade_delete.rs. |
| Propagate a type on assignment; replace a type, container or parent | Implemented | openbim-ifc::AuthorOp::AssignType with AssignTypeOptions maps the type's RepresentationMaps onto each object as IfcMappedItem representations, derives an IfcMaterialLayerSetUsage or IfcMaterialProfileSetUsage from the type's set with documented defaults, and validates or synchronises PredefinedType; replace unassigns a previous type with what it propagated, and RelateOptions::replace moves an element to another container or aggregate parent. Refusing remains the default; one transaction. In every binding. IFC2X3, IFC4, IFC4X3 door and wall types: crates/openbim-ifc/tests/type_propagation/. |
| Assemble, assign, copy and remove shape representations | Implemented | openbim-ifc::AuthorOp::ShapeRepresentation assembles an IfcShapeRepresentation from items in a geometric context, its RepresentationType checked against the items by the release's IfcShapeRepresentationTypes (CorrectItemsForType) or inferred as the most specific listed type, its identifier from the sub-context; AssignRepresentation adds it to a product's IfcProductDefinitionShape or wraps it in a type's new IfcRepresentationMap, refusing a second use (IfcShapeModel.WR11); UnassignRepresentation, CopyRepresentation (items copied, context, styles and type maps shared) and RemoveRepresentation (the #478 cascade, shared items kept). In every binding (batch operations; remove_representation). IFC2X3, IFC4, IFC4X3: crates/openbim-ifc/tests/shape_representation.rs. |
| Copy products and entities; append from another model | Implemented | openbim-ifc::AuthorOp::CopyProduct copies a product or type object with what RemoveProduct would remove with it (placement, moved or replaced by option; representation by CopyRepresentation's rules; own property sets, material usage, ports; openings and fillings by option) and shares what it would keep, the copy joining the type assignment, shared property sets, classification and, by option, container and whole; a CopyReport maps every original to its copy. AuthorOp::CopyEntity deep-copies by an explicit share/copy policy. apply_append copies entities with their closure from another model, reusing equal units, contexts, owner history, materials and styles, moving attributes by name between releases (refused with IncompatibleRelease where the target lacks one), refusing differing length or angle units (UnitMismatch), and keeping, merging or regenerating GlobalIds. In every binding (copy_product, append, batch operations). IFC2X3, IFC4, IFC4X3: crates/openbim-ifc/tests/copy_product.rs, append_model.rs. |
Authoring
Applications that generate IFC name attributes; the schema decides positions.
use ifc::EntityBuilder; // feature = "author"
let id = EntityBuilder::new(&schema, "IfcAnnotation")
.text("GlobalId", "3vB2YO$MX4xv5uCqZZG05x")
.text("Name", "Brandwand")
.insert(&mut model)?;Slot order comes from Schema::attributes, which returns inherited attributes first — the ordering positional STEP records depend on. IfcAnnotation gets seven slots because IFC4 declares seven, not because the caller counted.
Construction is refused, rather than silently accepted, for:
| Failure | Example |
|---|---|
| Unknown entity | IfcAnnotaton (typo) |
| Unknown attribute | IfcAnnotation.RefLatitude (belongs to IfcSite) |
| Attribute set twice | two Name calls, instead of a silent overwrite |
| Required attribute unset | IfcAnnotation with no GlobalId |
| Declared-type mismatch | a string where IfcLengthMeasure is declared |
| Scalar/aggregate confusion | a scalar where LIST OF is declared |
| Malformed GlobalId | not 22 characters in IFC's base-64 alphabet |
A refused build leaves the model untouched.
What this is not. WHERE rules, inverse attributes, uniqueness, and cross-entity consistency need a whole model rather than one entity; ifc-validate owns those. Value checking is deliberately permissive where a declared type cannot be resolved — see ADR 0007 for why authoring is a schema-layer concern and not a model-layer one.
Model::push remains public and unchecked, for the case where an application must write an entity the schema does not declare.
Spatial traversal
IFC stores no parent pointers: a wall does not name its storey, a relationship entity names both ends. ifc-spatial reads those relationships into a tree.
use ifc::{SpatialKind, SpatialTree}; // feature = "spatial"
let tree = SpatialTree::build(&model);
for level in tree.of_kind(SpatialKind::Storey) {
for element in tree.elements_of(level.id) {
println!("{element} is placed directly on {}", level.id);
}
}
let home = tree.container_of(wall); // which storey is this wall on?
let above = tree.ancestors(storey); // storey -> building -> site -> project
let beneath = tree.elements_recursive(building); // everything beneath a containerThe trap this closes. The two relationships that build the tree disagree about slot order — IfcRelAggregates puts the parent in slot 4, IfcRelContainedInSpatialStructure puts it in slot 5. Reading one like the other inverts containment silently. The constants are asserted against IFC2x3, IFC4 and IFC4x3 in crates/ifc-spatial/tests/slot_layout.rs; see ADR 0008.
Real files, not the ideal shape. Omitted sites, elements hung directly off a building, duplicate storeys, relationships naming absent entities, and containment cycles are all handled and, where they are defects, reported through orphans() and dangling() rather than dropped. One corpus fixture turned out to use IfcRelAggregates exclusively with no containment relationship at all; that case is pinned in tests/real_files.rs.
Containers come from the declared release. An entity is a spatial container when the release in FILE_SCHEMA declares it an IfcSpatialElement (IFC2X3: IfcSpatialStructureElement), so the IFC4X3 facilities (IfcRoad, IfcBridge, IfcRailway, IfcMarineFacility) and their parts hold elements like a storey does. Containment or reference into something that is not a container is reported through anomalies().
Contained is not referenced. IfcRelReferencedInSpatialStructure adds an element to structures it spans without being contained there (a curtain wall contained by the ground floor and referenced by the storeys above). referenced_elements() and referencing_structures() answer it apart from elements_of() and container_of(), so a multi-storey element never looks contained twice.
What this is not. It reports what the file says and never rejects it — cardinality and WHERE rules belong to ifc-validate. It groups elements; it does not interpret their geometry or properties. The facade's spatial_properties (features spatial and properties) joins the two: each container's contained, part and referenced elements with their exact properties, an error reported on the element it concerns.
Construction resources
With facade feature resource, ifc-resource selects IFC4 ADD2 TC1 or IFC4X3 ADD2 from the model header and exposes borrowed views for labor, equipment, crew, construction material, construction product, and subcontract occurrences. It resolves authored IfcResourceTime, validates and queries IfcRelAssignsToResource including its authored RelatedObjectsType category constraint, and walks resource composition through IfcRelNests with authored order plus explicit cycle, multiple-parent, depth, and node failures. Selected records and relationships can be created through schema-checked transaction-staged drafts; they reject duplicate GlobalId values and cycle/second-parent creation before staging. See the construction-resource guide.
This is a partial, deliberately bounded profile covering IFC4 and IFC4X3. It does not level or schedule resources, calculate costs/durations/quantities, interpret calendars, or claim IFC2X3 support (the schema does not declare the entities this crate projects).
Geometry
ifc-geometry is the largest crate in the workspace. It resolves IFC units, placements, profiles, and representation relationships, then lowers implemented families into the neutral axiolid-model DAG.
Representation-item lowering
The dispatcher keeps coverage as data so it is auditable from one table (crates/ifc-geometry/src/lower/dispatch.rs). The table covers IFC4 ADD2 TC1 and IFC4X3 ADD2: crates/ifc-geometry/tests/schema_coverage.rs lists the representation items IFC4X3 adds from IFC4X3_ADD2.exp, and fails when one is neither implemented nor planned with a reason.
| Family | Status |
|---|---|
IfcExtrudedAreaSolid | Implemented |
IfcRevolvedAreaSolid | Implemented |
IfcBooleanResult | Implemented |
IfcBooleanClippingResult | Implemented |
IfcMappedItem | Implemented |
IfcFacetedBrep | Implemented |
IfcFacetedBrepWithVoids | Implemented |
IfcAdvancedBrep | Implemented |
IfcAdvancedBrepWithVoids | Implemented |
IfcHalfSpaceSolid | Implemented |
IfcBoxedHalfSpace | Implemented |
IfcPolygonalBoundedHalfSpace | Implemented |
IfcTriangulatedFaceSet | Implemented |
IfcTriangulatedIrregularNetwork | Partial — 2 authored form(s) refused; see variants |
IfcPolygonalFaceSet | Implemented |
IfcCsgSolid | Implemented |
IfcSweptDiskSolid | Implemented |
IfcSweptDiskSolidPolygonal | Implemented |
IfcSurfaceCurveSweptAreaSolid | Implemented |
IfcBlock | Implemented |
IfcSphere | Implemented |
IfcRightCircularCylinder | Implemented |
IfcRightCircularCone | Implemented |
IfcRectangularPyramid | Implemented |
IfcBoundingBox | Implemented |
IfcExtrudedAreaSolidTapered | Implemented |
IfcRevolvedAreaSolidTapered | Implemented |
IfcFixedReferenceSweptAreaSolid | Implemented |
IfcDirectrixDerivedReferenceSweptAreaSolid | Partial — 1 authored form(s) refused; see variants |
IfcSectionedSpine | Implemented |
IfcShellBasedSurfaceModel | Implemented |
IfcFaceBasedSurfaceModel | Implemented |
IfcFaceSurface | Implemented |
IfcAdvancedFace | Implemented |
IfcGeometricSet | Implemented |
IfcGeometricCurveSet | Implemented |
IfcLine | Implemented |
IfcCircle | Implemented |
IfcEllipse | Implemented |
IfcPolyline | Implemented |
IfcIndexedPolyCurve | Implemented |
IfcCompositeCurve | Implemented |
IfcCompositeCurveOnSurface | Implemented |
IfcBoundaryCurve | Implemented |
IfcOuterBoundaryCurve | Implemented |
IfcTrimmedCurve | Implemented |
IfcOffsetCurve2D | Implemented |
IfcOffsetCurve3D | Implemented |
IfcPcurve | Partial — 2 authored form(s) refused; see variants |
IfcSurfaceCurve | Partial — 1 authored form(s) refused; see variants |
IfcIntersectionCurve | Implemented |
IfcSeamCurve | Implemented |
IfcBSplineCurveWithKnots | Implemented |
IfcRationalBSplineCurveWithKnots | Implemented |
IfcPlane | Implemented |
IfcCylindricalSurface | Implemented |
IfcSphericalSurface | Implemented |
IfcToroidalSurface | Implemented |
IfcSurfaceOfLinearExtrusion | Implemented |
IfcSurfaceOfRevolution | Implemented |
IfcRectangularTrimmedSurface | Implemented |
IfcCurveBoundedPlane | Implemented |
IfcCurveBoundedSurface | Implemented |
IfcBSplineSurfaceWithKnots | Implemented |
IfcRationalBSplineSurfaceWithKnots | Implemented |
IfcPointOnCurve | Implemented |
IfcPointOnSurface | Implemented |
IfcCurveSegment | Partial — 3 authored form(s) refused; see variants |
IfcGradientCurve | Partial — 3 authored form(s) refused; see variants |
IfcPointByDistanceExpression | Partial — 3 authored form(s) refused; see variants |
IfcAxis2PlacementLinear | Partial — 1 authored form(s) refused; see variants |
IfcOffsetCurveByDistances | Partial — 1 authored form(s) refused; see variants |
IfcSectionedSolidHorizontal | Partial — 1 authored form(s) refused; see variants |
IfcSectionedSurface | Partial — 1 authored form(s) refused; see variants |
IfcClothoid | Planned — an IfcSpiral is unbounded (-inf < u < inf) and the neutral intrinsic curve needs a finite arc length; it lowers exactly as the ParentCurve of an IfcCurveSegment |
IfcSecondOrderPolynomialSpiral | Planned — an IfcSpiral is unbounded (-inf < u < inf) and the neutral intrinsic curve needs a finite arc length; it lowers exactly as the ParentCurve of an IfcCurveSegment |
IfcThirdOrderPolynomialSpiral | Planned — an IfcSpiral is unbounded (-inf < u < inf) and the neutral intrinsic curve needs a finite arc length; it lowers exactly as the ParentCurve of an IfcCurveSegment |
IfcSeventhOrderPolynomialSpiral | Planned — an IfcSpiral is unbounded (-inf < u < inf) and the neutral intrinsic curve needs a finite arc length; it lowers exactly as the ParentCurve of an IfcCurveSegment |
IfcCosineSpiral | Planned — an IfcCosineSpiral or IfcSineSpiral law depends on the length L of the IfcCurveSegment using it; it lowers exactly only as the ParentCurve of an IfcCurveSegment |
IfcSineSpiral | Planned — an IfcCosineSpiral or IfcSineSpiral law depends on the length L of the IfcCurveSegment using it; it lowers exactly only as the ParentCurve of an IfcCurveSegment |
IfcPolynomialCurve | Planned — an IfcPolynomialCurve is unbounded (-inf < u < inf) and the neutral vocabulary has no unbounded polynomial curve; it lowers exactly as the ParentCurve of an IfcCurveSegment |
IfcSegmentedReferenceCurve | Planned — IfcSegmentedReferenceCurve segments are curves in the (distance along, deviating elevation) space of its base curve, and no normative rule maps a segment's ParentCurve and placement Axis to a cant law and pivot: implementations differ in the coefficient scaling (cant kappaL or kappaL^2) and the cross slope (sine or tangent of cant over rail head distance); the business cant layout lowers to a banked curve through ifc-alignment (#311) |
Partially supported variants
Families marked Partial above lower some authored forms exactly and refuse others by name. This table is generated from the PARTIAL catalog in crates/ifc-geometry/src/lower/dispatch.rs, and tests/lower_dispatch_corpus.rs drives the real lowering path for every row -- so a wrong disposition here fails CI rather than merely misinforming a reader.
Some of these refusals exist because the schema permits a combination the geometry cannot honour, rather than because the feature is unimplemented. Those are listed with their reasoning in Schema looseness.
| Family | Variant | Status | Rationale |
|---|---|---|---|
IfcAxis2PlacementLinear | Axis and RefDirection absent, or 3D and not parallel | Admitted | an OrientedCurveStation: the ratios are components in the curve's (tangent, left, up) frame, Axis exact and RefDirection orthogonalised against it, as 8.9.3.4 states |
IfcAxis2PlacementLinear | Location is refused as an IfcPointByDistanceExpression | Refused | the placement is its station; see IFCPOINTBYDISTANCEEXPRESSION |
IfcCurveSegment | ParentCurve is an IfcLine, IfcCircle or 2D IfcPolyline, measured by IfcLengthMeasure | Admitted | a line, arc or polyline cut by arc length and placed rigidly is elementary: a polyline or an angle-trimmed circle |
IfcCurveSegment | ParentCurve is an IfcSpiral subtype, measured by IfcLengthMeasure | Admitted | the spiral's curvature law, rebased to the segment in closed form, on a planar intrinsic curve; nothing is integrated |
IfcCurveSegment | SegmentLength is zero (the closing segment of a layout) | Admitted | its placement exactly: a planar intrinsic curve of length zero |
IfcCurveSegment | ParentCurve is a 2D IfcPolynomialCurve with a degree-one coordinate, cut forwards from SegmentStart 0 | Admitted | its Bezier over a closed-form parameter bound, placed rigidly and trimmed at TrimSelector::ArcLength: the kernel inverts the arc length, nothing is integrated here |
IfcCurveSegment | ParentCurve is an IfcPolynomialCurve cut from a non-zero SegmentStart, walked backwards, 3D, or with no degree-one coordinate | Refused | the placed start point inverts a non-elementary arc-length integral, a 3D polynomial has no plane for the placement, and without a degree-one coordinate the trim has no closed-form parameter bound |
IfcCurveSegment | SegmentStart or SegmentLength is an IfcParameterValue | Refused | SegmentStart/SegmentLength given as IfcParameterValue: IFC4.3 ADD2 defines no parametric space for IfcCurveSegment parents yet (informal proposition 1 requires IfcLengthMeasure) |
IfcCurveSegment | Placement is an IfcAxis2PlacementLinear, the segment met on its own or in a plain IfcCompositeCurve | Admitted | an InstanceAtStation: the parent's piece in local coordinates placed in the frame of the OrientedCurveStation the placement lowers to, local X, Y, Z on the station's tangent, left and up as 8.9.3.4 reads them; the kernel resolves the station |
IfcCurveSegment | Placement is an IfcAxis2PlacementLinear in an IfcGradientCurve | Refused | an IfcAxis2PlacementLinear placement stands at a station along a basis curve, which only a kernel resolves; a segment of an IfcGradientCurve is read as a plan or profile piece and needs a resolved placement |
IfcDirectrixDerivedReferenceSweptAreaSolid | directrix defines only a tangent (no IfcCurveSegment, segment-built or surface curve reachable) | Admitted | IFC4.3 gives it exactly the behaviour of IfcFixedReferenceSweptAreaSolid in this case, so it lowers to the same FixedReferenceSweep |
IfcDirectrixDerivedReferenceSweptAreaSolid | directrix defines a tangent plane | Refused | kernel: the directrix defines a tangent plane (it is built from IfcCurveSegment placements or lies on a surface), so the derived reference adds that plane's rotation to FixedReference; the neutral FixedReferenceSweep carries only a constant reference direction |
IfcGradientCurve | horizontal IfcCurveSegments over lines, arcs, spirals and 2D IfcPolynomialCurves; vertical IfcCurveSegments over IfcLine, IfcCircle, an IfcSpiral subtype, or a degree-2 IfcPolynomialCurve that keeps its start tangent | Admitted | one plan parameterised by arc length (an intrinsic curve, or an arc-length chain with a polynomial piece) plus a piecewise elevation law of polynomial, circular and intrinsic pieces: Curve3::Elevated, exact |
IfcGradientCurve | a vertical parabola or spiral with no following segment, closing segment or EndPoint | Refused | its plan extent inverts a non-elementary arc-length integral, and nothing states it |
IfcGradientCurve | a heading kink, a closed-form position gap, or a profile that does not span the base curve | Refused | one plan curve and one elevation law cannot carry a kink or a gap, and an elevation law must cover the whole plan |
IfcGradientCurve | placed by a frame that tilts, scales or mirrors the vertical | Refused | a plan plus a height is carried only by frames that keep the vertical axis |
IfcOffsetCurveByDistances | OffsetValues along its own BasisCurve, spanning it or on a basis with a stated length, across its tangent discontinuities too | Admitted | OffsetByStations, linear between the offsets; a span short of the ends is carried on unchanged to them by added stations, as 8.9.3.42.3 states; mitred at a seam like the sweeps on the same stations (8.8.3.35.1) |
IfcOffsetCurveByDistances | OffsetValues short of the ends of a bounded basis whose length lies at an arc-length integral (an offset beside a gradient curve, a spiral, a B-spline or an ellipse, a relation with an ellipse or a B-spline piece, a B-spline or an ellipse) | Admitted | OffsetsAtStations continued by stations at the basis's start and end, whose distances the kernel measures (RunStation::at_basis_start / at_basis_end, axiolid/kernel#303, #433), as 8.9.3.42.3 states; stations carry the kernel's seam-snapping window where the seams are quadratures (#429); a stated station at or past the end the kernel measures is refused by it by name |
IfcOffsetCurveByDistances | offsets short of an unbounded end, a non-zero OffsetLongitudinal, a member on another basis, or a run across a seam where the basis turns back on itself | Refused | an unbounded line has no end to continue the offsets to and the neutral offset curve stops at its last station, IFC states no law for a longitudinal offset along a curve, and a mitre has no plane at a reversal |
IfcPcurve | reference curve is an IfcPolyline | Admitted | an ordered 2D point sequence needs no evaluation |
IfcPcurve | reference curve is an IfcIndexedPolyCurve with no explicit Segments, or only IfcLineIndex segments | Admitted | reads identically to a plain ordered point sequence |
IfcPcurve | reference curve is an IfcLine, IfcCircle or IfcEllipse positioned by an IfcAxis2Placement2D | Admitted | defining values are read verbatim in the surface's own (u, v) domain with no unit conversion |
IfcPcurve | reference conic positioned by an IfcAxis2Placement3D | Refused | a 3D placement's axis has no meaning in a 2D parameter domain; admitting it would require inventing a projection |
IfcPcurve | reference curve is an IfcIndexedPolyCurve with an explicit IfcArcIndex segment | Admitted | a three-point arc composes exactly from a parameter-space circumcentre into Circle2 plus a Cartesian trim, mirroring the 3D path with no approximation |
IfcPcurve | reference curve is an explicit-knot IfcBSplineCurveWithKnots or IfcRationalBSplineCurveWithKnots | Admitted | every field is dimensionless or a curve parameter; knots already pass through the 3D path unscaled, and control points are read as raw (u, v) pairs |
IfcPcurve | reference curve is a trimmed or composite curve | Admitted | trim parameters and segments stay in the surface (u, v) domain, unscaled, so no dimensional contract is needed |
IfcPcurve | reference curve is a convention-only IfcBSplineCurve | Refused | a base spline carries no authored knot vector to preserve |
IfcPointByDistanceExpression | DistanceAlong is an IfcLengthMeasure on the basis curve, on or off its tangent discontinuities | Admitted | a CurveStation: distance (plan distance on a gradient curve, arc length otherwise) and the lateral (left), vertical and longitudinal offsets, in the same frame IFC4.3 ADD2 8.9.3.48 states; within precision of a seam, at the seam reading SeamSide::Incoming, since the previous segment's tangent governs (8.9.3.48.3) |
IfcPointByDistanceExpression | DistanceAlong is an IfcParameterValue | Refused | IFC4.3 ADD2 gives most basis curves no parameterisation a distance can be read from, and a neutral station is a distance |
IfcPointByDistanceExpression | DistanceAlong on a composite, trimmed or surface curve, or on segments placed at stations, whose pieces' lengths are stated by their data | Admitted | a station along the curve relation, measured end to end through its pieces (axiolid/kernel#285); every joint is a seam, and within precision of one the station stands on it reading SeamSide::Incoming, the previous segment (8.9.3.48.3) |
IfcPointByDistanceExpression | DistanceAlong on a basis whose tangent discontinuities lie at arc-length integrals: an offset whose length is a quadrature (beside a gradient curve, a spiral, a B-spline or an ellipse, or a variable offset of a circle), a relation with an ellipse or a B-spline piece, a B-spline with a corner knot | Admitted | an OrientedCurveStation at its own distance reading SeamSide::Incoming, with the model's precision as its seam-snapping window (axiolid/kernel#294, #423): the kernel reads it on a seam within the window, from the previous segment (8.9.3.48.3), at its own certified distance, and refuses two seams in the window, a seam on its edge and a length it cannot certify by name |
IfcPointByDistanceExpression | DistanceAlong on an IfcOffsetCurve2D/3D or an IfcOffsetCurveByDistances of lines, polylines or circles (a constant offset of a circle in its plane) | Admitted | a station along the offset relation, in the offset's own length (axiolid/kernel#289); every seam of the basis and every OffsetValues station is a joint, and within precision of one the station stands on it reading SeamSide::Incoming, the previous segment (8.9.3.48.3); IFC's positive Distance (anticlockwise normal) is Axiolid's left |
IfcPointByDistanceExpression | DistanceAlong on an offset of an offset, a trim of an offset, an offset through a circle's centre, or an offset across a corner of its basis | Refused | kernel: Axiolid measures a station along an offset of atomic pieces whose sides meet, in its own length |
IfcPointByDistanceExpression | DistanceAlong on a relation joining gradient curves with other pieces | Refused | kernel: no one distance runs through pieces measured in plan distance and in arc length |
IfcSectionedSolidHorizontal | area sections at positions along the Directrix, across its tangent discontinuities too | Admitted | SectionsAtStations in the curve's frame, matched by ring and index; RefDirection is the profile normal and Axis profile Y (IFC4.x-IF#147, IFC4.x-development#1010); a seam is mitred at half angle (8.8.3.35.1) |
IfcSectionedSolidHorizontal | area sections along a Directrix whose seams lie at arc-length integrals (an offset beside a gradient curve, a spiral, a B-spline or an ellipse, or a B-spline corner knot) | Admitted | each section carries the model's precision as the kernel's seam-snapping window, reading SeamSide::Incoming (axiolid/kernel#301, #429): the kernel snaps it onto a seam within the window and mitres there at half angle (8.8.3.35.1), and refuses two seams in a window, a seam on its edge, a length it cannot certify and positions no longer increasing once snapped by name |
IfcSectionedSolidHorizontal | positions off the Directrix, or spanning a seam where it turns back on itself | Refused | a station measures along its own basis, and "very sharp edges may result in nearly impossible miter" (8.8.3.35.1) |
IfcSectionedSurface | open sections tagged throughout or not at all, with one tag set | Admitted | OpenSectionsAtStations joined by tag, forwards or reversed; profile X to the left as IfcOpenCrossProfileDef states (8.15.3.15.1, #344) |
IfcSectionedSurface | open sections along a Directrix whose seams lie at arc-length integrals | Admitted | as IFCSECTIONEDSOLIDHORIZONTAL: each section carries the kernel's seam-snapping window and the incoming side (axiolid/kernel#301, #429), mitred at half angle where it snaps (8.8.3.37.1) |
IfcSectionedSurface | mixed tagging or branching breaklines (sections with different Tags) | Refused | the neutral surface joins one tag set through every section |
IfcSurfaceCurve | MasterRepresentation is Curve3D, PCurveS1, or PCurveS2 with the named side present | Admitted | each side pairs a surface with its own p-curve, so the neutral MasterRepresentation names S1 and S2 exactly |
IfcSurfaceCurve | MasterRepresentation is PCurveS2 with only one associated p-curve | Refused | the master names a parametric side the curve does not have; the schema calls this inconsistent, so it is refused rather than resolved to the remaining p-curve |
IfcTriangulatedIrregularNetwork | every Flags value is a breakline code, 0 to 7 | Admitted | a breakline marks an edge the triangulation already has, so the triangle surface is the supertype's; the flags are not carried into the mesh |
IfcTriangulatedIrregularNetwork | a Flags value is -1 (hole) or -2 (void) | Refused | the triangle is excluded from the surface, and a hole may fall back on another surface; the neutral mesh has no face-exclusion or fall-back channel |
IfcTriangulatedIrregularNetwork | a Flags value is outside -2 to 7 | Refused | the documentation defines no meaning for it |
Coverage below is generated
The table above is derived from crates/ifc-geometry/src/lower/dispatch.rs by cargo run -p xtask -- docs, and scripts/gate.sh fails when this page and that source disagree. It cannot drift from the code without breaking the build.
Unimplemented families return a typed GeometryError::Unsupported naming the source entity and the specific missing capability — never a panic, and never a silently substituted approximate shape.
Profile lowering
Swept solids reference a profile, so profile coverage bounds how much of a real model lowers. Steel sections carry their fillet radii, edge radii and flange slopes into the neutral model rather than being reduced to an outline, because a section without them has the wrong area and the wrong section modulus.
An arbitrary profile's boundary is either an IfcPolyline or an IfcCompositeCurve of polylines, trimmed circles and lines, and nested composites. Arcs stay exact. A composite whose segments do not meet within 1e-5 m is refused rather than closed with an edge the file never authored, and any other boundary curve family is refused by name.
| Profile family | Status |
|---|---|
IfcArbitraryClosedProfileDef | Implemented |
IfcArbitraryOpenProfileDef | Implemented |
IfcArbitraryProfileDefWithVoids | Implemented |
IfcAsymmetricIShapeProfileDef | Implemented |
IfcCenterLineProfileDef | Implemented |
IfcCircleHollowProfileDef | Implemented |
IfcCircleProfileDef | Implemented |
IfcCompositeProfileDef | Implemented |
IfcCShapeProfileDef | Implemented |
IfcDerivedProfileDef | Implemented |
IfcEllipseProfileDef | Implemented |
IfcIShapeProfileDef | Implemented |
IfcLShapeProfileDef | Implemented |
IfcMirroredProfileDef | Implemented |
IfcOpenCrossProfileDef | Implemented |
IfcRectangleHollowProfileDef | Implemented |
IfcRectangleProfileDef | Implemented |
IfcRoundedRectangleProfileDef | Implemented |
IfcTShapeProfileDef | Implemented |
IfcTrapeziumProfileDef | Implemented |
IfcUShapeProfileDef | Implemented |
IfcZShapeProfileDef | Implemented |
IfcProfileDef | Refused — generic profile declaration carries no concrete geometry to lower |
IfcArbitraryOpenProfileDef is implemented through the explicit lower_open_profile_node authored-path API. It is not an area profile and is therefore still refused when an extrusion or other area-based solid requests lower_profile.
The boundary curves of IfcArbitraryClosedProfileDef and IfcArbitraryProfileDefWithVoids lower from IfcPolyline, IfcCompositeCurve (polylines, trimmed circles and lines, nested composites) and IfcIndexedPolyCurve (line and exact three-point arc segments, or one polyline without Segments). An arc whose three points are collinear within the model's Precision is the polyline through them, as IFC prescribes. An open boundary, an arc with coincident points and SelfIntersect TRUE are refused as degenerate, never closed or chorded; other curve families are refused as unsupported.
Curves and placement
| Capability | Status | Module |
|---|---|---|
IfcPolyline, IfcIndexedPolyCurve | Implemented | exact line and three-point arc segments; an arc collinear within the model's Precision is its polyline segment, as IFC prescribes (#396) |
IfcCircle, IfcEllipse | Implemented | curve/conic.rs |
IfcLine | Implemented | curve/line.rs |
IfcTrimmedCurve | Implemented | curve/trimmed.rs |
IfcCompositeCurve | Implemented | curve/composite.rs |
Convention-only IfcBSplineCurve | Partial | typed view only; lowering does not invent absent knots |
IfcBSplineCurveWithKnots, IfcRationalBSplineCurveWithKnots | Implemented | curve/bspline.rs representation + exact neutral lowering |
IfcOffsetCurve2D/3D | Implemented | curve/offset.rs |
IfcPcurve, IfcSurfaceCurve, IfcIntersectionCurve | Partial | exact supported forms; typed refusal otherwise |
IfcAxis2Placement2D/3D | Implemented | resource/placement.rs |
IfcCartesianTransformationOperator* | Implemented | resource/operator.rs |
| Unit resolution (SI, conversion-based) | Implemented | units.rs |
Curves lower in nested and curve-representation paths
lower/curve.rs lowers polylines/indexed poly-curves, conics, lines, trims, composites, offsets and surface-associated curves, plus explicit-knot polynomial/rational B-splines into the neutral graph. Convention-only base splines remain unsupported. Curves reach this lowerer through a sweep directrix, a surface boundary, a B-rep edge, or an IfcGeometricCurveSet member.
Bare curves are dispatch targets for Curve2D, Curve3D, and plan representations. Selection remains explicit: callers choose Body or Plan; a plan curve never silently replaces a body.
Explicit-knot surfaces
| Capability | Status | Module |
|---|---|---|
Convention-only IfcBSplineSurface | Partial | typed view only. Lowering requires an explicit knot vector, so IfcBSplineSurfaceWithKnots lowers and the convention-only parent form does not: deriving the implied knots would be inventing geometry the file did not state. |
Representation selection
Two selectors, deliberately disagreeing:
use ifc::{select_plan_representation, select_shape_representation};
let body = select_shape_representation(&model, wall)?; // what a 3D viewer draws
let outline = select_plan_representation(&model, wall)?; // what a drawing drawsselect_shape_representation prefers Body, then Facetation, then an unnamed representation, and refuses Axis/FootPrint so a 2D curve never silently replaces a solid.
select_plan_representation is its inverse. It prefers, in order:
- a
PLAN_IDENTIFIERSmatch inside aPLAN_VIEWsub-context — drawable geometry the author explicitly targeted at a plan; - otherwise the best
PLAN_IDENTIFIERSmatch in any context:Plan,Annotation,FootPrint,Axis.
The two rules are intersected, not ordered. Authorial intent selects between drawable candidates; it does not make a bounding box drawable. ArchiCAD writes Box/BoundingBox representations inside PLAN_VIEW sub-contexts, so a context-first rule returns those boxes and never reaches the identifier list.
It returns None for a solid-only or box-only product. That is the honest answer, not a failure: deriving a plan from a solid requires sectioning, which this library does not do — see R9b/R10 on the roadmap.
Representation context
| Capability | Status | Evidence |
|---|---|---|
IfcGeometricRepresentationContext | Implemented | RepresentationContext; identifier, type, precision, placement |
IfcGeometricRepresentationSubContext | Implemented | parent, target scale, target view |
TargetView (PLAN_VIEW, MODEL_VIEW, ...) | Implemented | typed enum; unknown constants preserved, not flattened |
| Authoring a plan sub-context | Implemented | ifc_georef::create_representation_subcontext (parent context, identifier, target view, with the ParentNoSub and UserTargetProvided rules); also constructible via EntityBuilder |
use ifc::plan_contexts; // feature = "geometry-select"
for context in plan_contexts(&model) {
let scale = context.target_scale(); // Some(0.01) for 1:100
let precision = context.precision(&model); // inherited from the parent context
println!("plan view at {scale:?}, precision {precision:?}");
}The * trap this closes. A sub-context redeclares six inherited attributes as DERIVED, and real files write them as *:
IFCGEOMETRICREPRESENTATIONSUBCONTEXT('Body','Model',*,*,*,*,#1,$,.MODEL_VIEW.,$)* is not $ — it means "read this from my parent". Accessors that take &model (precision, world_coordinate_system, coordinate_space_dimension, true_north) walk ParentContext to resolve it. A consumer reading the slot directly gets the marker and loses the project's precision and placement. See ADR 0009.
Slot positions are asserted against IFC2x3, IFC4 and IFC4x3 in crates/ifc-geometry/tests/context_slots.rs, including that the sub-context still inherits exactly six attributes — the off-by-six that would read TargetScale as the target view.
Presentation, annotation, and external references
These are the areas most relevant to drawing production and document/approval workflows. Presentation and annotation have schema-resolved typed views and bounded transaction-staged authoring; rendering and drawing layout remain outside the domain contracts. Approvals and constraints have bounded typed views and authoring (the whole approval resource schema is not claimed). External classification/document/library references have typed read/query/authoring coverage.
| Entity / concept | Status | Note |
|---|---|---|
IfcAnnotation | Implemented | Strict borrowed view and transaction-staged authoring; IFC4X3 PredefinedType remains version-conditional |
IfcTextLiteral, IfcTextLiteralWithExtent | Implemented | Strict literal/placement/path/extent views and transaction-staged authoring |
IfcAnnotationFillArea | Implemented | Type-checked outer/inner boundary views and transaction-staged authoring |
IfcCurveStyle, IfcFillAreaStyle | Implemented | Schema-resolved curve/font/fill/hatch/tile views; no rendering claim |
IfcSurfaceStyle and children | Implemented | RGB/factor, shading, rendering, lighting, refraction, and texture views; core surface graph authoring |
IfcPresentationLayerAssignment | Implemented | Layer membership/style/visibility view and styled-layer authoring |
IfcStyledItem | Implemented | Strict direct assignment view/writer and deterministic direct-over-layer resolution; IFC2x3 wrappers are explicit |
IfcShapeRepresentation | Absent | Generic Representation view exists; the subtype does not |
IfcGeometricRepresentationSubContext | Partial | Strict inherited view and plan-context query exist; authoring uses generic EntityBuilder, not a dedicated helper |
IfcLibraryReference | Implemented | Strict borrowed view and transaction-staged authoring |
IfcLibraryInformation | Implemented | Strict borrowed view and transaction-staged authoring |
IfcRelAssociatesLibrary | Implemented | Deterministic object lookup and transaction-staged authoring |
IfcExternalReference and IfcLibrarySelect | Implemented | Inherited fields are exposed by concrete views; select targets are type-checked |
IfcExternalReferenceRelationship | Implemented | ifc-classification owns strict selected projections, deterministic lookup, and transaction-staged authoring |
IfcApproval and selected approval relationships | Implemented | ifc-approval owns bounded IFC4 projections, queries, and transaction-staged authoring; the whole IfcApprovalResource schema is not claimed |
IfcMetric, IfcObjective, and selected constraint relationships | Implemented | ifc-constraint preserves typed metric values and stages bounded IFC4 authoring without evaluating constraints |
IfcClassificationReference | Implemented | Bounded hierarchy, explicit occurrence/type sources, and authoring |
Because ifc-model round-trips entities structurally, every row above reads and re-exports without loss. The status distinguishes that baseline from typed interpretation and authoring; only rows marked implemented expose those domain contracts.
Explicit non-goals
- A CAD modelling kernel. Booleans, tessellation, and NURBS evaluation live in Axiolid or its providers.
- Rendering, drawing layout, or paper-space composition.
- Vendored ISO or buildingSMART schema payloads (the contributing guide).
- Any C++ in the dependency graph.
- IFC5 / IFCX and a JSON serialisation of the EXPRESS releases (ADR 0020).
How to verify a claim on this page
- Read the crate's public API and its
tests/directory. - Read the crate's
README.mdand module docs for its design notes, and its reference page for its latest release notes. - Run the gate:
scripts/gate.sh. It regenerates every table on this page and on the coverage page and fails if the committed copy differs. - For geometry coverage, read
crates/ifc-geometry/src/lower/dispatch.rs; the tables above are generated from itsIMPLEMENTED,PLANNEDandPARTIALconstants, which tests assert against the schema.