Skip to content

@ifc-lite/renderer@1.28.3

Choose a tag to compare

@louistrue louistrue released this 17 Jun 18:12
· 41 commits to main since this release
2e8ea66

Patch Changes

  • #1160 631511e Thanks @louistrue! - Restore per-layer slicing of single-solid walls/slabs with an IfcMaterialLayerSetUsage. Slicing turns one solid into one coloured sub-mesh per material layer (geometry_id = the layer's IfcMaterial) so the build-up is visible in 3D. The "Merge Multilayer Walls" toggle now does what its label promises for these walls too — "render walls as one solid": with the toggle on, the layer index is not attached, so each wall stays a single swept solid instead of slicing into layers (off, the default, shows the layered build-up).

    The slicing kernel stayed intact, but #874 (mesh-production unification) dropped the set_material_layer_index wiring from every pipeline, so the router's index was always None and try_layered_sub_meshes never fired — layered walls silently rendered as a plain single solid in the browser, native, and server paths. Re-wire it: build the MaterialLayerIndex once per load (cached on the IfcAPI for the streaming path, with a cheap substring bail-out so files with no layer set pay nothing) and attach it to every batch router. This also restores the "Merge Multilayer Walls" toggle for models whose sliceable walls carry their geometry as IfcBuildingElementParts — the merged parent now actually draws its sliced solid instead of leaving a gap.

    2D section now shows the layers too. The section cutter carries each sub-mesh's colour onto its cut segments (CPU and GPU paths), and the polygon builder splits one entity's cut into a polygon per material colour — single-material elements still produce one colourless polygon, so their existing per-ifcType / per-entity fill is unchanged. When the viewer shows IFC materials, each sliced layer fills with its own IfcMaterial colour instead of one colour for the whole wall, and the layer divisions are drawn as outlines — matching the 3D build-up.

    Two follow-on robustness fixes:

    • 3D layer glitch (z-fighting). Adjacent layer slabs share the parent wall's expressId, so the renderer's per-entity depth nudge (keyed on entityId) gave their coincident interior interface caps the SAME depth — under cullMode: 'none' + MSAA that z-fought into a flickering comb that read as "see inside / not solid". The shader now folds the per-draw baseColor into the depth-nudge hash; batches are keyed by colour, so abutting layers (distinct colours) land on distinct depths. Constant per draw, so flat faces stay flat and curved surfaces are unaffected.

    • Cap watertightness on irregular profiles. A layer slab's innermost cut is built by two successive plane clips; on a non-convex IfcArbitraryClosedProfileDef the two passes deposit geometrically-coincident section vertices that differ by ~1 ULP. cap_half_space_clip welded by exact f32 bits, so those twins stayed separate, the boundary chain dead-ended and a cap sub-loop was silently dropped — leaving open edges (a hole you could see through and a section with no fill there). The cap now welds on a spatial grid tied to its on-plane tolerance, collapsing the twins so the loop closes. Single-plane callers (opening cuts) have no such twins and are unaffected.

    • 3D section cut read hollow. The live 3D section cap (Section2DOverlayRenderer) filled each cut polygon with a naive convex fan over the outer ring only, ignoring holes — a long-standing KNOWN LIMITATION. On the concave cross-sections that arbitrary IFC profiles (and material-layer slabs) cut into, the fan inverts and leaves the cut face uncovered, so a sectioned wall read as a hollow shell. The fill now uses the renderer's existing hole-aware ear-clipping (the same one the annotation-fill path uses), so the cut face is solid. The cap also now honours a per-polygon colour: a material-layer wall fills each layer of its 3D section cut with that layer's IfcMaterial colour (matching the 3D solids and the 2D section), while single-material cuts keep the uniform cap style + hatch unchanged via a sentinel.

    • Solid layered 3D walls via backface culling. Rendering a material-layer wall as N thin coincident-faced layer solids made it shimmer / read as a hollow shell — adjacent layers' interface caps z-fight under the viewer's double-sided rendering (culling is globally off because general IFC winding is unreliable), and same-material adjacent layers can't be depth-separated. The layer slices DO have reliable outward winding, though, so they're now tagged geometryClass 3 and the renderer draws that class with a dedicated backface-culling pipeline: the build-up stays visible on the wall's faces and edges, but the interior coincident caps never rasterise, so the wall reads as a clean solid (and a section cut through it shows the interior material surface rather than a hollow shell). The 2D/section cut consumes the same class — it never culls — for its per-layer fills. Cache FORMAT_VERSION → 9 so stale caches re-mesh with the class-3 slices.

  • Updated dependencies [631511e]:

    • @ifc-lite/geometry@2.7.6