IFClite TypeScript API
    Preparing search index...

    Interface StepAdapterOptions

    interface StepAdapterOptions {
        buildExclusions?: boolean;
        federation?: FederationLike;
        meshes: MeshData[];
        meshIdOffset?: number;
        modelId: string;
        store: IfcDataStore;
        worldTransform?: Mat4;
    }
    Index
    buildExclusions?: boolean

    Precompute void/host/assembly exclusions. Default true.

    federation?: FederationLike

    When provided, ref is the federated globalId; otherwise the expressId.

    meshes: MeshData[]
    meshIdOffset?: number

    The federation offset the HOST has ALREADY added to every mesh.expressId, so this adapter can subtract it back out and address store in its own (local) id space. Default 0 — meshes are local.

    The viewer's loader shifts meshes into the global id space in place (useIfcLoader: mesh.expressId = mesh.expressId + idOffset) while IfcDataStore keeps LOCAL ids, so for every federated model past the first mesh.expressId is NOT a key into store. Without this, every lookup in the loop below misses: key degrades to the synthetic fallback, tag reads Unknown, name/storey come back empty, and buildStepExclusions finds no relationships at all — so void/host/assembly pairs silently stop being excluded. ref was wrong in the other direction, with federation.toGlobalId adding the offset a second time.

    tag degrades with the rest, despite the node.type || mesh.ifcType expression below reading as though the mesh could rescue it: every production EntityTable returns the literal string 'Unknown' from getTypeName on a miss, and 'Unknown' is truthy, so the mesh.ifcType arm is unreachable on a store lookup that missed. Unknown next to a blank name is the loudest on-screen symptom of this bug.

    The viewer's own compare path (lib/compare/buildFingerprints.ts) does the same subtraction for the same reason. The CLI / MCP / playground callers hand over local meshes and leave this at its 0 default.

    The obvious hardening is to make this REQUIRED, and the repo has the precedent: buildFingerprints.ts declares idOffset: number and does this exact subtraction, which is why compare never had this bug. It is deliberately NOT copied here. buildFingerprints is app-internal (apps/viewer), free to break at will; elementsFromStep is published API — @ifc-lite/clash exposes it as the ./step subpath export — so requiring the member is a breaking change for every external caller, all of which legitimately pass local meshes and would have to add a 0 to keep compiling. That is a major bump to harden one in-repo call site, on a patch-level bugfix.

    What covers the gap instead, since the optional signature is exactly what let the viewer wiring be deleted and stay green:

    • apps/viewer/src/hooks/useClash.federated-id-offset.test.tsx pins the viewer's call at the level that actually broke (it fails if meshIdOffset is dropped from gatherElements);
    • the total-miss console.warn at the end of elementsFromStep reports a forgotten offset at RUNTIME, in any host, including new ones — for any model whose store actually holds GlobalIds. It stays silent for a store that holds none (a GLB import), where a total miss is the normal state and warning would only teach the reader to ignore the message.

    A dev-only expressId < 0 assert was considered and rejected: it fires only when the subtrahend is too LARGE, whereas the failure that shipped was a forgotten offset, i.e. a subtrahend of 0 producing positive, plausible, entirely wrong ids. It would not have caught this bug. The total-miss check keys on the damage instead, so it catches both directions.

    modelId: string

    Model/file id (federation).

    worldTransform?: Mat4

    Aligns this model into the common world frame (RTC + building rotation).