Expand description
Canonical IFC styling — the single source of truth for mesh colors, shared between the HTTP server, the native pipeline, and the browser-side WASM bindings (issue #913).
This mirrors the [crate::symbolic] split: presentation logic that used
to be copied into every consumer (wasm-bindings, processing,
apps/server, the now-discontinued desktop app) lives here exactly once.
See issue #913 for the design and rationale.
Phase 0 (this commit) introduces only the two pieces with no decoder or
geometry dependency — the canonical Rgba color type and the single
default_color_for_type table — and wires nothing into the pipeline
yet. The decoder-driven resolver (StyleIndex, IfcStyledItem /
IfcIndexedColourMap / material-chain resolution) arrives in Phase 2.
§Canonical contracts
f32is canonical;u8is transport-only. Colors areRgba([f32; 4], straight-alpha,0.0..=1.0) end-to-end. The browser’s 8-bit SharedArrayBuffer transport is expressed only throughRgba::to_rgba8/Rgba::from_rgba8; the backend stays exact. (Decision §8.3 of the plan.)- One default table.
default_color_for_typeis the only IFC-type → color map in Rust. A CI guard (Phase 1) fails the build if a second one appears.
Structs§
- Full
Indexed Colour Map - A fully resolved
IfcIndexedColourMap: the palette plus a per-triangle index into it (inCoordIndexorder, which the triangulated-face-set processor preserves 1:1). - Geometry
Style Info - Resolved appearance of one geometry item (the value side of the styled-item index keyed by geometry express id).
- Mesh
Finish Join - The finish join over caller-held indexes: the wasm batch, which already
holds its colour index (as
id -> rgba) and the installed finishes, and decodes through its own per-batch decoder. - Model
Finishes - The finish join resolved from a file’s bytes alone, for a consumer that
holds nothing but the file and its produced meshes (the server’s
transports). One scan collects the styled items and the entity index; the
colour index is the pipeline’s own (
resolve_styled_items_into, every styled item resolved, as the finished pipeline has them) and the finish index is the one the wasm prepass ships. - Rgba
- Canonical straight-alpha RGBA color, components in
0.0..=1.0. - Specular
Material - Metallic/roughness evidence read from one
IfcSurfaceStyleRendering. Either field isNonewhen the file carries no evidence for it; the renderer’spackMeshMaterialthen falls back to its own default (DEFAULT_MATERIAL_METALLIC/DEFAULT_MATERIAL_ROUGHNESS).
Constants§
- TRANSPARENCY_
ALPHA_ THRESHOLD - Alpha at or above which a color is treated as opaque.
Functions§
- build_
element_ material_ colors - Build the
element id → material coloursmap: every colour each element inherits from its associated material(s), in resolution order. The single general-path fallback picks the first opaque colour (pick_opaque_first); the opening sub-mesh path alternates transparent/opaque (pick_material_style_for_submesh) to split glass vs frame. - build_
material_ style_ index - material id → colours, by following each material’s styled representations to the orphan styled items they reference.
- default_
color_ for_ type - The canonical default color for an IFC type.
- extract_
surface_ style_ colors - Extract the apparent surface colour (and an optional distinct shading colour)
from an
IfcSurfaceStyle, walking itsStyleslist (attr 2) and returning the first rendering’s(apparent, shading)pair. - extract_
surface_ style_ specular - Extract the metallic/roughness pair from an
IfcSurfaceStyle’s firstIfcSurfaceStyleRendering, walking itsStyleslist (attr 2) exactly asextract_surface_style_colorsdoes, so the two never disagree about which rendering “wins” for a multi-styleIfcSurfaceStyle. - fixed_
display_ color_ for_ type - The colour a class ALWAYS renders with, overriding any authored styling, or
Nonefor the ordinary style precedence. - flatten_
material_ color_ index - Flatten a
material id → coloursmap intomaterial id → colourby picking the first opaque colour per material (pick_opaque_first). Used to key layered sub-mesh colour lookups on material id — each layer slice’sgeometry_idis itsIfcMaterialentity id. - pick_
material_ style_ for_ submesh - Pick a material colour for one sub-mesh, alternating preference so a window
distributes its frame (opaque) and glazing (transparent) colours across
sub-meshes instead of painting every part the same.
prefer_transparentis toggled by the caller per sub-mesh. - pick_
opaque_ first - Pick the first opaque colour (alpha ≥ threshold), else the first colour.
- resolve_
indexed_ colour_ map_ full - Resolve an
IfcIndexedColourMapto its palette + per-triangle indices. - resolve_
material_ ids - Resolve a material
SELECTto the individualIfcMaterialids it contains. - resolve_
submesh_ color - Resolve one sub-mesh’s colour, given its already-resolved direct-style colour.
- split_
mesh_ by_ indexed_ colour - Split a flat-shaded mesh into one sub-mesh per palette group.