npm.io
1.33.0 • Published 2d ago

@ifc-lite/renderer

Licence
MPL-2.0
Version
1.33.0
Deps
2
Size
1.6 MB
Vulns
0
Weekly
0

@ifc-lite/renderer

WebGPU-based 3D renderer for IFClite. Zero-copy from WASM linear memory to GPU buffers, hardware frustum culling, GPU-accelerated picking, section planes, multi-model federation.

Installation

npm install @ifc-lite/renderer

Render an IFC model

import { Renderer } from '@ifc-lite/renderer';
import { GeometryProcessor } from '@ifc-lite/geometry';

const renderer = new Renderer(canvas);
const geometry = new GeometryProcessor();
await Promise.all([renderer.init(), geometry.init()]);

const meshes = [];
for await (const event of geometry.processAdaptive(new Uint8Array(buffer))) {
  if (event.type === 'batch') meshes.push(...event.meshes);
}
renderer.loadGeometry(meshes);
renderer.requestRender();

loadGeometry() accepts a GeometryResult from @ifc-lite/geometry or a raw MeshData[]. The renderer keeps geometry in GPU buffers; subsequent requestRender() calls coalesce into a single frame.

Pick an entity

canvas.addEventListener('click', async (e) => {
  const rect = canvas.getBoundingClientRect();
  const hit = await renderer.pick(e.clientX - rect.left, e.clientY - rect.top);

  if (hit) {
    console.log(`Clicked expressId ${hit.expressId} at`, hit.point);
    renderer.setSelection([hit.expressId]);
    renderer.requestRender();
  }
});

For exact world-space hits with surface normals, use raycastScene(x, y) — slower but returns the precise intersection point + normal.

Section planes

// Cut the model with an axis-aligned section plane
renderer.setSectionPlane({
  axis: 'down',          // 'side' | 'down' | 'front' (X / Y / Z)
  position: 3.0,         // metres along axis
  enabled: true,
  flipped: false,
});
renderer.requestRender();

// Disable
renderer.setSectionPlane(null);

Visibility + colour overrides

// Hide a list of entities
renderer.setHiddenEntities(new Set([12345, 12346, 12347]));

// Solo a subset (everything else gets the ghost treatment)
renderer.setIsolatedEntities(new Set([42]));

// Tint specific entities
renderer.setColorOverrides(new Map([
  [42, [1, 0, 0, 1]],   // RGBA — bright red
  [99, [0, 1, 0, 0.4]], // semi-transparent green
]));
renderer.requestRender();

Multi-model federation

import { federationRegistry } from '@ifc-lite/renderer';

// Register each model with a unique ID offset
federationRegistry.registerModel('arch', maxArchExpressId);
federationRegistry.registerModel('struct', maxStructExpressId);

// Now picks return globalIds; resolve back to (modelId, expressId)
const hit = await renderer.pick(x, y);
const { modelId, expressId } = federationRegistry.fromGlobalId(hit.expressId);

API

See the Rendering Guide and API Reference.

License

MPL-2.0

Keywords