Module scene

Source
Expand description

A flat, renderer-neutral render scene over a composed node tree.

RenderScene::from_composition walks the composed tree of [openbim_ifcx::compose()] once and returns everything a viewer draws:

  • Instances: one per drawn geometry of a node, with the node’s path (for picking), its world Transform, a GeometryRef into the shared buffers, a material index, and world bounds;
  • shared geometry buffers: MeshBuffer (triangles with vertex normals), LineBuffer (line segments), PointBuffer (points with optional colours), all f32;
  • the Material table;
  • the scene’s f64 world Bounds and the render origin;
  • SceneWarnings for attribute values that could not be decoded.

§Walk

Starting at the artificial root, each node is visited once per path that reaches it, parents before children, children in composed order. For each node:

  1. An invisible node is left out with its whole subtree (is_visible).
  2. Its world transform is its usd::xformop applied in its parent’s world transform (world_from_parent); a node without one inherits it.
  3. A mesh is drawn with the nearest gltf::material, else the nearest diffuseColor with its own opacity, else grey 0.6 opaque; curves use the latter two only (resolve_mesh_material, resolve_basic_material).
  4. Each of its mesh, curves, and point cloud becomes an instance.

Instance paths name the node by child names from the root, as site/Storey/Wall, which [Composition::get] resolves. Instance::node is the path of the node that defined it, [ComposedNode::path].

§Instancing

Composition shares sub-trees and attribute values through Arc: every node that inherits a type, or names the same child, holds the same attribute value. The scene decodes each distinct value once, keyed by its Arc pointer, and stores one buffer that all instances reference. Equal values written separately in a file are not merged.

§Precision and origin

Coordinates stay f64 until the end. Each buffer stores its vertices relative to an anchor, the centre of the geometry’s own bounding box, so f32 keeps sub-millimetre precision even for georeferenced vertices (upstream samples reach 4.9 × 10⁶ m in mesh points). The scene’s origin is subtracted from world coordinates; by default it is the centre of the world bounds. Each instance’s render matrix maps buffer coordinates to world coordinates minus the origin: anchor, then world transform, then origin shift, multiplied in f64 and rounded to f32 last. Add the origin back, for example as a root translation, to place the scene in the file’s coordinates.

§Differences from the reference viewer

The reference viewer is src/viewer/render.ts of buildingSMART/IFC5-development at 1a63082.

  • A node with a mesh, curves, and a point cloud yields all three; the viewer draws only the first of mesh, curves, point cloud. No upstream example has two kinds on one node.
  • The viewer applies no transform to the root it is given, which is always the artificial root without attributes. RenderScene::from_root applies the given node’s transform like any other.
  • The viewer draws lines in 0.8 times the resolved colour. The scene keeps the resolved colour; the darkening is a styling choice for renderers.
  • The viewer draws pcd::base64 points without colours in white, through three.js PCDLoader’s default, and other points without colours in black. The scene uses black for all of them.
  • The viewer computes vertex normals with three.js computeVertexNormals; so does the scene, area-weighted over the triangles that share a vertex. A vertex in no triangle with an area gets +Z, so that every normal is a unit vector.
  • See presentation for opacity 0, visibility: "inherited", and all-false glTF materials.

§Mirroring

A world transform with a negative determinant mirrors its geometry and reverses the winding of its triangles. Buffers are shared between instances and keep the file’s winding; Instance::mirrored reports these instances, and renderers flip their front face (glTF viewers and three.js do so from the node matrix).

§Warnings

Building a scene does not fail. A value that cannot be decoded becomes a SceneWarning with the node path and attribute id, and only that value is skipped: a malformed mesh leaves out the mesh, a malformed colour falls back to the inherited one. A malformed usd::xformop leaves out the node with its subtree, since nothing below it can be placed. Linear curves of an unsupported type are skipped with a warning as well. Each distinct value is reported once, at the first path that reaches it. Empty geometry is skipped without a warning.

Buffers and render matrices are f32, so coordinates they cannot hold are left out with a SceneWarningKind::OutOfRange warning rather than written as infinities: a geometry whose vertices span more than f32::MAX, and an instance whose world bounds reach beyond a quarter of f32::MAX (about 8.5 × 10³⁷) or whose render matrix overflows f32. Every value in a scene is therefore finite.

§Limits

Composition shares sub-trees, so a small file can describe a tree whose paths are exponential in number: 30 nodes that each name the next twice as children reach the last one along 2³⁰ paths. The walk visits a node once per path, so SceneOptions bounds it: at most max_visits node visits (10 million by default) and at most max_path_bytes bytes of instance paths built (1 GiB by default). When either is reached the walk stops, the scene keeps what was walked before, and one SceneWarningKind::LimitReached warning names the path where it stopped.

Structs§

Bounds
An axis-aligned box in f64.
Instance
One drawn geometry of one node at one path.
LineBuffer
Shared line segments, from the linear curves of usd::usdgeom::basiscurves.
MeshBuffer
A shared triangle mesh, from usd::usdgeom::mesh.
PointBuffer
Shared points, from pcd::base64, points::array, or points::base64.
RenderScene
A flat render scene; see the module docs.
SceneOptions
Options for RenderScene::from_composition.
SceneWarning
A value skipped while building a scene; see the module docs.

Enums§

GeometryKind
The kind of geometry an instance draws.
GeometryRef
What an instance draws: an index into one of the scene’s buffer lists.
Origin
Where the render origin of a scene lies.
SceneWarningKind
Why part of a node was left out of a scene.