Skip to content

3D Viewer & Analysis

The view and analyze commands turn the CLI into a visual BIM analysis tool. Launch an interactive WebGL 2 viewer in the browser, then drive it from the terminal, scripts, or AI assistants via a REST API.

Optional feature

The viewer is provided by @ifc-lite/viewer-core. All other CLI commands work without it — it only activates when you run view or analyze.

view — Launch 3D Viewer

# Open a model in the browser
ifc-lite view model.ifc

# Fixed port (useful for scripting)
ifc-lite view model.ifc --port 3456

# Don't auto-open the browser
ifc-lite view model.ifc --port 3456 --no-open

# Empty scene — build geometry via API
ifc-lite view --empty --port 3456

Flags:

Flag Description
--port <N> Listen on a specific port (default: random)
--no-open Don't open the browser automatically
--empty Start with an empty scene (no IFC file)
--send <json> Send a command to an already-running viewer (requires --port)

Interactive Console

While the viewer is running, type commands directly in the terminal:

colorize IfcWall red        # Color all walls red
isolate IfcWall IfcSlab     # Show only walls and slabs
xray IfcWall 0.15           # Make walls transparent
highlight 42 43             # Highlight entities by express ID
flyto IfcDoor               # Fly camera to doors
view front                  # Switch to front view
storey                      # Color by building storey
section y center            # Add horizontal section plane
clearSection                # Remove section plane
clear                       # Remove live-created geometry
showall                     # Show all entities
reset                       # Reset colors and visibility
quit                        # Stop the viewer

Named colors: red, green, blue, yellow, orange, purple, cyan, white, pink.

Send Commands from Another Terminal

Use --send to control a running viewer without opening a new one:

ifc-lite view --port 3456 --send '{"action":"colorize","type":"IfcWall","color":[1,0,0,1]}'
ifc-lite view --port 3456 --send '{"action":"setView","view":"top"}'
ifc-lite view --port 3456 --send '{"action":"isolate","types":["IfcWall","IfcSlab"]}'

REST API

The viewer exposes a REST API on the same port. Use it from curl, scripts, or AI tools.

POST /api/command — Send Viewer Commands

curl -X POST http://localhost:3456/api/command \
  -H 'Content-Type: application/json' \
  -d '{"action":"colorize","type":"IfcWall","color":[1,0,0,1]}'

Returns {"ok": true, "action": "colorize", "clients": 1} on success.

Type-Level Actions

These operate on all entities of a given IFC type:

Action Payload Description
colorize {type, color} Color all entities of a type
isolate {types: [...]} Show only listed types
xray {type, opacity?} Make a type semi-transparent
flyto {type} Fly camera to a type
highlight {ids: [...]} Highlight express IDs
colorByStorey {} Auto-color by building storey
setView {view} Set camera: front, back, left, right, top, bottom, iso
showall {} Reset visibility
reset {} Reset all colors and visibility

Entity-Level Actions

These operate on specific express IDs:

Action Payload Description
colorizeEntities {ids, color} Color specific entities
isolateEntities {ids} Show only specific entities
hideEntities {ids} Hide specific entities
showEntities {ids} Show previously hidden entities
resetColorEntities {ids} Reset colors on specific entities

Section Planes

Action Payload Description
section {axis, position} Add section plane. Axis: x, y, or z. Position: number, "center", or "50%"
clearSection {} Remove section plane

POST /api/create — Live Element Creation

Create IFC elements and inject them into the viewer in real time. Accepts a single object or an array for batch creation.

# Single element
curl -X POST http://localhost:3456/api/create \
  -H 'Content-Type: application/json' \
  -d '{"type":"wall","params":{"Height":3,"Start":[0,0,0],"End":[5,0,0]}}'

# Batch create (single HTTP call)
curl -X POST http://localhost:3456/api/create \
  -H 'Content-Type: application/json' \
  -d '[
    {"type":"wall","params":{"Height":3,"Start":[0,0,0],"End":[5,0,0]}},
    {"type":"wall","params":{"Height":3,"Start":[5,0,0],"End":[5,5,0]}},
    {"type":"slab","params":{"Width":5,"Depth":5}}
  ]'

Returns entity list and IFC size:

{"ok":true,"count":3,"entities":[...],"ifcSize":3646}

All 30+ element types from the create command are supported. Coordinates use IFC Z-up convention.

POST /api/clear-created — Remove Live Geometry

curl -X POST http://localhost:3456/api/clear-created

Removes all geometry added via /api/create from the viewer and server state.

GET /api/export — Download Created Geometry

curl http://localhost:3456/api/export > created.ifc

Downloads all live-created geometry as a valid IFC STEP file.

GET /api/status — Server Status

curl http://localhost:3456/api/status
{"ok":true,"model":"Building.ifc","clients":1,"createdSegments":2}

analyze — Visual Analysis Overlay

Query entities by type and properties, then push the results as color overlays to a running viewer. Requires a viewer to be running first.

# Start the viewer
ifc-lite view model.ifc --port 3456 --no-open &

# Find walls missing fire rating — color them red
ifc-lite analyze model.ifc --viewer 3456 \
  --type IfcWall --missing "Pset_WallCommon.FireRating" --color red

# Heatmap by slab area
ifc-lite analyze model.ifc --viewer 3456 \
  --type IfcSlab --heatmap "Qto_SlabBaseQuantities.GrossArea" --palette blue-red

# Filter by property value
ifc-lite analyze model.ifc --viewer 3456 \
  --type IfcWall --where "Qto_WallBaseQuantities.GrossSideArea>50" --color orange

# Isolate + color + fly to
ifc-lite analyze model.ifc --viewer 3456 \
  --type IfcDoor --isolate --color green --flyto

Flags:

Flag Description
--viewer <port> Port of the running viewer (required)
--type <T> IFC type to analyze (e.g. IfcWall)
--missing <Pset.Prop> Find entities missing a property
--where <expr> Property filter: Pset.Prop>100, Pset.Prop=true
--color <name> Color matched entities (named or r,g,b,a)
--heatmap <Pset.Prop> Color by numeric value (gradient)
--palette <name> Heatmap palette: blue-red, green-red, rainbow
--isolate Hide non-matching entities
--flyto Fly camera to matched entities
--rules <file.json> Run multiple rules from a JSON file
--json Machine-readable output

Rules File

Run multiple analysis rules in one pass using a JSON file:

[
  {
    "name": "Missing fire rating",
    "type": "IfcWall",
    "missing": "Pset_WallCommon.FireRating",
    "color": "red",
    "isolate": true
  },
  {
    "name": "Large slabs",
    "type": "IfcSlab",
    "where": "Qto_SlabBaseQuantities.GrossArea>100",
    "color": "orange"
  },
  {
    "name": "Wall area heatmap",
    "type": "IfcWall",
    "heatmap": "Qto_WallBaseQuantities.GrossSideArea",
    "palette": "blue-red"
  }
]
ifc-lite analyze model.ifc --viewer 3456 --rules rules.json --json

Coordinate Convention

IFC uses Z-up; the WebGL viewer uses Y-up internally. The WASM geometry engine handles the conversion automatically during mesh parsing. When using /api/create, pass coordinates in IFC Z-up convention ([x, y, z] where Z is vertical).

Architecture

graph LR CLI["CLI / curl / AI"] -->|REST API| Server["@ifc-lite/viewer-core<br/>Node.js HTTP"] Server -->|SSE push| Browser["WebGL 2 Viewer<br/>Browser"] Server -->|Stream IFC| Browser Browser -->|WASM parse| Render["GPU Render"]

The viewer is a self-contained WebGL 2 application served as a single HTML page. Commands flow from external tools through the REST API, get broadcast to connected browsers via Server-Sent Events (SSE), and execute in the WebGL renderer.

Key design decisions:

  • IFC streamed from disk — large models aren't buffered in Node.js memory
  • WASM geometry engine — parsing and mesh generation happen in the browser
  • GPU color-ID picking — click any entity to see its express ID and type
  • Per-vertex color buffer — real-time colorization without re-uploading geometry
  • SSE with exponential backoff — reconnects automatically if the connection drops
  • CORS restricted to localhost — the API only accepts requests from local origins

Programmatic Usage (@ifc-lite/viewer-core)

The viewer server can be used as a library in your own Node.js tools:

import { startViewerServer } from '@ifc-lite/viewer-core';

const viewer = await startViewerServer({
  filePath: 'model.ifc',
  fileName: 'My Model',
  port: 3456,
  onReady: (port, url) => console.log(`Viewer at ${url}`),
});

// Send commands programmatically
viewer.broadcast({ action: 'colorize', type: 'IfcWall', color: [1, 0, 0, 1] });
viewer.broadcast({ action: 'setView', view: 'iso' });

// Check connected clients
console.log(`${viewer.clientCount()} browsers connected`);

// Clean up
viewer.close();

Exports:

Export Description
startViewerServer(opts) Start the HTTP + SSE server
VALID_ACTIONS Set<string> of accepted command actions
getViewerHtml(title) Get the self-contained viewer HTML
createStreamingViewerAdapter(port) SDK adapter for bim.viewer.* calls
ViewerServer Server instance type
CreateHandler Handler type for /api/create