WOODFINE CAPITAL PROJECTS BIM Design System

IfcGeometricRepresentationItem

viewport 3d

Universal AEC interface component. Anchored to IfcGeometricRepresentationItem in the IFC 4.3 hierarchy; classified as Uniclass FI_60_30. Consumed by app-workplace-bim (Tauri 2.10 + xeokit) and app-console-bim (web-only read surface) under the mode-prop pattern.

IFCIfcGeometricRepresentationItemUniclassFI_60_30modeworkplace · consolecode overlays0 registered
Preview

Viewport mounts at runtime. xeokit-bim-viewer in workplace mode; static SVG plan-thumbnail in console mode (EUPL-1.2 boundary).

Camera: (0.000, 0.000, 0.000) No selection
recipe.html
<!-- bim-viewport-3d — universal AEC interface component.
     Hosts the 3D viewer canvas. v0.0.1 recipe shows the placeholder
     surface; the runtime integration in app-workplace-bim mounts a
     xeokit-bim-viewer into this container.

     Mode prop: workplace (selection sync with SpatialTree, section
     planes editable, BCF viewpoint capture) | console (selection
     read-only; no edit affordances).

     Note: workplace integration is AGPL-3.0 due to xeokit coupling.
     Console integration may use a non-3D fallback (static SVG plan
     thumbnail) at v0.0.1 to preserve EUPL-1.2.
-->

<section class="bim-viewport-3d" data-mode="console" aria-label="3D viewport">
  <div class="bim-viewport-3d__chrome">
    <div class="bim-viewport-3d__navcube" aria-hidden="true">
      <span class="bim-viewport-3d__navcube-face">N</span>
    </div>
    <div class="bim-viewport-3d__toolbar" role="toolbar" aria-label="Viewport controls">
      <button type="button" aria-label="Fit to view" disabled>⌘⊕</button>
      <button type="button" aria-label="Section plane" disabled>▭</button>
      <button type="button" aria-label="Capture viewpoint" disabled>◉</button>
    </div>
  </div>
  <div class="bim-viewport-3d__canvas-host">
    <canvas class="bim-viewport-3d__canvas" aria-label="3D model canvas"
            width="800" height="600"></canvas>
    <p class="bim-viewport-3d__placeholder">
      Viewport mounts at runtime. xeokit-bim-viewer in workplace mode;
      static SVG plan-thumbnail in console mode (EUPL-1.2 boundary).
    </p>
  </div>
  <footer class="bim-viewport-3d__statusbar">
    <span class="bim-viewport-3d__coords">Camera: (0.000, 0.000, 0.000)</span>
    <span class="bim-viewport-3d__selection">No selection</span>
  </footer>
</section>
recipe.css
.bim-viewport-3d {
  position: relative;
  width: 100%;
  height: 100%;
  background: #1a1a1a;
  display: flex;
  flex-direction: column;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  color: #e5e7eb;
}

.bim-viewport-3d__chrome {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  z-index: 10;
}

.bim-viewport-3d__navcube {
  width: 4rem;
  height: 4rem;
  background: #fff;
  border: 1px solid #d1d5db;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #1a1a1a;
  font-weight: 600;
  font-size: 0.85rem;
}

.bim-viewport-3d__toolbar {
  background: #fff;
  border: 1px solid #d1d5db;
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  padding: 0.25rem;
  gap: 0.25rem;
}

.bim-viewport-3d__toolbar button {
  width: 2.25rem;
  height: 2.25rem;
  border: none;
  background: transparent;
  cursor: pointer;
  font-size: 0.85rem;
  color: #1a1a1a;
  border-radius: 3px;
}

.bim-viewport-3d__toolbar button:hover:not([disabled]) {
  background: #e5e7eb;
}

.bim-viewport-3d__toolbar button[disabled] {
  opacity: 0.4;
  cursor: not-allowed;
}

.bim-viewport-3d__canvas-host {
  flex: 1;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
}

.bim-viewport-3d__canvas {
  width: 100%;
  height: 100%;
  display: block;
}

.bim-viewport-3d__placeholder {
  position: absolute;
  color: #6b7280;
  font-size: 0.85rem;
  text-align: center;
  max-width: 24rem;
  margin: 0;
  padding: 0 1rem;
}

.bim-viewport-3d__statusbar {
  background: #0a0a0a;
  border-top: 1px solid #2a2a2a;
  padding: 0.4rem 0.75rem;
  font-size: 0.75rem;
  font-family: "SF Mono", Menlo, Consolas, monospace;
  color: #9ca3af;
  display: flex;
  justify-content: space-between;
  gap: 1rem;
}
aria.md

bim-viewport-3d — accessibility

Role and structure

  • Container is <section aria-label="3D viewport">.
  • 3D canvas is <canvas aria-label="3D model canvas"> — canvas content is not directly inspectable by AT; selection state is surfaced via the status bar and the live bim-properties-panel.
  • Toolbar is <div role="toolbar" aria-label="Viewport controls"> with <button> children carrying aria-label.
  • The NavCube is presentational (aria-hidden="true"); functionally duplicated by keyboard view-direction shortcuts (1–6 for ±X / ±Y / ±Z).

Selection synchronisation

  • Selecting an element in the canvas updates the live region in bim-properties-panel (host integration).
  • Selection from bim-spatial-tree (key-actuated) flows to the viewport via host integration.

Keyboard navigation

| Key | Action | |---|---| | 1 / 2 / 3 / 4 / 5 / 6 | View along ±X / ±Y / ±Z axes (NavCube equivalent) | | F | Fit selected element / fit view if no selection | | Arrow keys | Pan (with shift) or orbit | | + / - | Zoom in / out | | S | Toggle section plane | | B | Capture BCF viewpoint (workplace mode only) | | Tab | Move focus to toolbar |

Mode-prop behaviour

  • data-mode="workplace" — toolbar buttons enabled; xeokit-bim-viewer embeds at host-integration time; AGPL-3.0 distribution.
  • data-mode="console" — toolbar buttons disabled; viewport optionally degrades to static SVG plan thumbnail to preserve EUPL-1.2 boundary; selection arrives from SpatialTree only (no canvas selection).

Don't

  • Don't pipe IFC bytes over IPC. xeokit canvas loads XKT files via convertFileSrc() + Tauri's asset: protocol; large model data never crosses the IPC boundary. (BB.3 finding.)
  • Don't bundle xeokit's standalone CSS; let the runtime integration pull it via npm/CDN per host-framework decision.
IFC mapping
TokenIFC anchorUniclass
bim-viewport-3dIfcGeometricRepresentationItemFI_60_30

Component renders the IfcGeometricRepresentationItem family. See the token taxonomy research for the full IFC × Uniclass cross-walk.

Code overlays applicable

This token's IFC anchor (IfcGeometricRepresentationItem) accepts IfcConstraint relationships from any jurisdictional code overlay registered in service-codes. Composition order: municipal → provincial → federal → accessibility.

No overlays registered for IfcGeometricRepresentationItem in this jurisdiction. First Woodfine BC RS-1 encoding lands at v0.0.3 (per sub-agent B's 6–8 week roadmap).

How City Code as Composable Geometry works →