vflow2 Documentation

IFC Analysis Tools ← Back to App

3D/2D Viewer

Purpose

Interactive web-based viewer for IFC building models with multiple overlay systems. Uses Three.js for rendering and web-ifc for parsing IFC geometry in the browser.

File

templates/viewer.html — single-page application, self-contained.

Views

3D viewer with storey panel

3D Perspective View (default)

2D Plan View

2D plan view

Overlay Systems

Element Sidebar

Space Containers

Connection Graph

MEP Cable Routes

Installation Zones

Storey Filter

Storey filter — single storey selected

Background Job System

Coordinate Mapping

The Problem

IFC files use one coordinate system. web-ifc (with COORDINATE_TO_ORIGIN) may remap and shift axes when loading geometry. All backend data (routes, graph, zones, spaces) is computed in IFC world coordinates, but must be transformed to match the Three.js scene.

Auto-Detection Algorithm

  1. Compute IFC world bounding box (from /spaces/ endpoint: ifcWorldMin/Max)
  2. Compute Three.js model bounding box (THREE.Box3.setFromObject)
  3. Try all 48 permutation+sign combinations (6 axis permutations × 8 sign combos)
  4. For each candidate: check size match (tolerance 1.0m), compute offset
  5. Pick mapping with minimum error (transformed space bbox fits within model bbox)

Result

coordMapping = {
  perm: [0, 2, 1],     // perm[threeAxis] = ifcAxis
  sgn:  [1, -1, 1],    // sign flip per axis
  off:  [0.0, 3.2, -10.4]  // translation offset
}

function ifcToThree(ifcPoint) {
  return new THREE.Vector3(
    sgn[0] * ifcPoint[perm[0]] + off[0],
    sgn[1] * ifcPoint[perm[1]] + off[1],
    sgn[2] * ifcPoint[perm[2]] + off[2],
  );
}

Usage

All overlay rendering functions call ifcToThree() to transform IFC coordinates before creating Three.js geometry. This single function handles the full mapping.

Performance Optimizations

State Management

Key JavaScript variables in the module scope:

Variable Type Purpose
elementMeshes Map Three.js meshes per IFC element
elementData Map Element metadata
coordMapping {perm, sgn, off} IFC↔Three.js coordinate transform
routeGroup THREE.Group Cable route overlay meshes
connGraphGroup THREE.Group Connection graph overlay
wallZoneGroup THREE.Group Installation zone overlays (renderOrder 1)
ceilingZoneGroup THREE.Group Ceiling zone overlays (renderOrder 1)
edgeGroup THREE.Group Wall outlines for 2D plan (child of allMeshGroup)
is2DPlan boolean Current view mode
wallZoneMode string "normal" | "false_ceiling" | "false_floor"
zoneDataCache object | null Cached zone JSON for fast storey rebuilds
storeyData array Storey list from /storeys/ endpoint
activeStoreyID number | null Selected storey (null = all)