Skip to content

v0.3.0

Choose a tag to compare

@DrunkOnJava DrunkOnJava released this 27 Sep 22:17
· 255 commits to main since this release
v0.3.0
36fb456

This release turns rvt-rs's IFC and glTF output from boxes in the right place into buildings that read like Revit's own export: walls, floors, roofs and ceilings as their layers and materials, elements named and placed on the storeys Revit gives them. Every figure below is measured against Revit's own IFC export of the same model; the reports under reports/element-framing/ hold the inputs and outputs.

Export you can check

  • Generated GlobalIds are stable between exports (#400). Entities Revit's export gives no GlobalId (openings, the further pieces of a slab, site, building, relationships, property sets) were numbered by their position in the file, so one more profile point renumbered everything after it. Each is now derived from the document's own GUID and the entity's identity. Exported before and after the curved-wall change, Snowdon Towers keeps all 20,149 GlobalIds, from 7,740. Revit's own GlobalIds are unchanged. One-time change: every generated GlobalId differs from 0.2.0's, so anything keyed by them needs one re-import.
  • The IFC declares the units its values are in (#403). Exports declared Revit's display units, or millimetres when none were found, over values written in metres: IfcOpenShell read a 20 ft wall as 6 mm. The unit assignment is now metres, square metres, cubic metres, radians, kilograms and seconds, and the same wall reads 6.096 m.
  • The whole schema is read (#410). Formats/Latest carries a checksum page every 65,249 bytes; stripping them makes the stream's own gzip checksum verify on all 23 corpus files and gives each release one schema. The 2024 schema now has 4,126 classes instead of 395.
  • Exports say how much of the model is a stand-in box (#409). The diagnostics count bodies by how they were derived, rvt-ifc prints the total, and the viewer's file status has a Shapes row. Core Interior: 274 of 970.
  • The IFC header names the version that wrote it (#417), not 0.1.x.

Element data

  • Every element carries its Revit class (RE-76): SWall, ArcWall, Floor, RoomElem, FamilyInstance and so on, read from the file's own schema. Every exported element on Core Interior, RE1 Architecture and Snowdon Towers resolves.
  • Type Mark, Description and Fire Rating (RE-77), from each element's type. On Snowdon Towers every value agrees with Revit's: Fire Rating on 696 of 696 elements against Revit's IFC4 export, Type Mark on 1,257 of 1,276 against the model's VIM export (the other 19 are empty there). Instance parameters are not read yet.
  • Electrical and mechanical devices and equipment (RE-79): switches, sensors, receptacles, fire alarm devices (IfcAlarm), data devices, panels and mechanical equipment. RE1 Electrical exports exactly the 49 elements of Revit's own export, from 12. The symbols nested in switches and receptacles are left out, as Revit leaves them out.

Layers and materials

  • Walls are drawn as their layers, each in its material's colour (RE-53), from their centreline at their type's thickness (RE-54), on Revit 2024 and 2025 (RE-55). On Autodesk's Snowdon Towers sample, every layer centre is within 0.001 ft of Revit's on 851 of 862 walls, and all 1,368 layer colours are Revit's.
  • A wall runs through a butt join or stops at it as its own join lists say (RE-70). Where two walls' centrelines meet, the wall that names the other runs on to its far face and the other stops at its near face, which agrees with every clean joint in Revit's export of Snowdon Towers. Each such end names the other wall in the IFC, and the viewer's element panel links to it.
  • Layered walls end layer by layer at their corners (RE-71). The layers nest like concentric Ls, the through wall's reaching the other wall's outer layer edges and the stopping wall's its inner edges, drawn as a staircase outline.
  • A wall that ends part way along another stops against it layer by layer (RE-73), by Revit's layer priorities: a core passes the other wall's finishes and stops at its core, and a finish stops at its face.
  • Walls that meet at an angle end on slanted lines (RE-74): the same joins apply at 45 to 135 degrees, each layer ending where its edges meet the other wall's line. On Snowdon Towers 716 of 1,078 walls now have both of Revit's ends (curved walls scored by radius and angle), and 4,394 of 5,634 layer ends match Revit's body.
  • Curved walls are drawn along their arc (RE-75), read from the same record as a straight wall's line. On Snowdon Towers the 24 curved walls have Revit's centre and radius, and their footprints overlap Revit's by a median 0.95, from 0.03.
  • Floors, roofs and ceilings are drawn as their layers, stacked top first (RE-57). Shed roofs follow their slope (RE-56).
  • The IFC export writes layer sets (RE-58): IfcMaterialLayerSetUsage over an IfcMaterialLayerSet, each layer with its material's name and thickness, named Family:Type as Revit names it (RE-61). Layer names are Revit's, in Revit's order, on 3,321 of Snowdon's 3,322 layers.
  • Material names are read from each material's own data (RE-58). The IFC's material list is the file's own materials rather than every material-like string (#34): 219 on Snowdon instead of 946. Every material Revit's export styles by name has Revit's colour, 174 of 174.

Names, storeys and structure

  • Elements are named as Revit names them. Walls, curtain walls, floors, ceilings, roofs and railings are named Family:Type:ElementId with ObjectType Family:Type (#322, RE-63), as family instances already were. So are slab edges, ramps and curtain panels that hold a basic wall (#370, RE-64), stairs with their runs, landings and stringers (RE-65), railings whose type has no element data (RE-66), model text (RE-67) and wall sweeps (RE-69). Core Interior's 854 elements all carry Revit's name, and on Snowdon Towers so do 2,109 of the 2,111 system-family elements.
  • Elements sit on the storeys Revit gives them (RE-59, RE-60, RE-68).
    • An element naming two Levels takes its base constraint.
    • A railing takes its host stair's storey.
    • Hosted elements take their work plane's Level where their elevation agrees.
    • A multistory stair takes the Level its base sits at, and slab edges, light fixtures, wall sweeps and other elements whose record names no Level take the one their base elevation gives, within a fail-closed band. Plumbing fixtures take their work plane's Level, as Revit does.
    • Core Interior binds all 970 building elements, each in Revit's storey. On Snowdon Towers 5,949 elements are on Revit's storey, 1 on none (from 1,931) and 1 on another.
  • Storeys carry their Level's name, elevation and GlobalId (RE-51). Elements, rooms and storeys carry Revit's own GlobalIds (RE-48).
  • Curtain walls export as IfcCurtainWall aggregates of their panels and mullions (RE-46, RE-62). A panel's curtain grid names its wall (RE-72), so all 2,075 of Snowdon's curtain parts sit in Revit's curtain wall, and panels that hold a basic wall are curtain walls with a body, as Revit writes them.
  • Revit's "Export to IFC As" overrides are honoured (RE-45).
  • Beams run along their location lines (RE-49).
  • Roofs carry their sketched outline (RE-50).
  • Stair flights are drawn as their treads and risers (RE-52), with Pset_StairCommon riser count, riser height and tread length (RE-47).

Speed

  • Large projects open about twice as fast (#381). rvt-ifc on Core Interior takes 2.75 s instead of 5.3 s, and on the 95 MB Snowdon Towers sample 10.1 s instead of 17.9 s. In the browser viewer Snowdon Towers opens in 24 seconds instead of 56. Output is byte-identical.
  • The partition string scan is about four times faster (#385): 0.22 s instead of 0.85 s over Snowdon's 443 MB of partitions, with the same 644,367 strings.

Viewer

  • The scene tree reads like Revit's browsers. Each storey opens to its categories, each with a count, and each category to its elements, sorted by family and type. Element rows show the type name first, with the family and ElementId underneath. A curtain wall opens to its panels and mullions, and a stair to its flights. Picking an element in the 3-D view opens its category, and the tree works from the keyboard. A filter above the tree, reached with /, finds elements by name, type or ElementId.
  • The Categories panel counts each category's elements.
  • The element panel shows the ElementId and Revit's own GlobalId.
  • A light scheme and a new look, on one design system.
  • Elements coloured by category where they have no material.
  • Zoom to an element with a double-click, F, or the info panel.
  • The element panel lists a selected element's layers, each a toggle that highlights every element using that material.

Fixes

  • Empty curtain panels are left out, as Revit's export leaves them out (#309): Snowdon Towers exports 6,021 elements, of which 76 are not in Revit's export, from 100.
  • The viewer and plan export draw each element's real body, upright.
  • Property text with non-ASCII characters is written as ISO 10303-21 escapes.
  • A material's colour is no longer read from a misaligned frame.
  • Orbiting no longer changes the selection.
  • Python wheels install on more Linux systems (manylinux2014, musllinux) and on Intel macOS, and PyPI receives wheels only.

Documentation

  • One capability story (#404): the README, status page and supported profile describe the same main, and rvt-capabilities --matrix prints the support matrix from any installed build.
  • A reference model pack (#407): every model the claims are measured on, with its licence and how its reference export was made, and tools/fetch-reference-models.sh to download the redistributable ones with their hashes checked.
  • The docs.rs front page (#406) states what the crate does, with three runnable entry points. The crate is on crates.io (cargo install rvt --locked) and its API on docs.rs.
  • The viewer shows the version it was built from.

API changes

  • Generated GlobalIds change once (#400), as above.

  • IFC length properties lose their "Feet" suffix (#398): ThicknessFeet is Thickness, JoinReachStartFeet is JoinReachStart, and so on. Their values were always in the file's metres. Anything that reads them by name needs the new names.

  • ifc::entities::MaterialLayer::material_index is Option<usize>.

  • IfcModel gains material_layer_usages and element_layers.

  • ElementLayers gains stacked and system_family.

  • LayerBand gains name and is no longer Copy.

  • ElementInfoPanel gains layers, whose rows are PanelLayer.

  • partition_schema_mvp::WallAxis gains join_reach_feet.

  • scene_graph::ElementInfoPanel gains joins (PanelJoin).

  • element_record_wall_joins::WallLine carries layers and exterior, and ButtJoin is no longer Copy.

  • element_record_wall_joins::tee_join is new, and butt_joins returns T joints too.

  • partition_beam_axes::BoundedArc and scan_first_bounded_arcs, partition_compound_structure::scan_wall_arcs and partition_schema_mvp::WallArc are new; first_bounded_line returns None where a curve record is an arc.

  • ButtJoin gains layer_edge_reach_feet, WallLayerEnds::reach_feet holds a pair per layer, and angled_layer_edges, angled_tee_edges and ANGLED_JOIN_MAX_COSINE are new.

  • element_record_level_refs::PLUMBING_LEVEL_OBJECT_SOURCE is new.

New fields default when deserialising.

The full list is in CHANGELOG.md.