[Astro] #122 IFC Viewer — web-ifc WASM によるブラウザ完結型 建築BIM IFCファイルビューア

[Astro] #122 IFC Viewer — web-ifc WASM によるブラウザ完結型 建築BIM IFCファイルビューア

概要

web-ifc(IFC.jsプロジェクトの中核WASMエンジン)を使い、IFC2X3・IFC4・IFC4X3の建築BIMデータをブラウザ内で3D表示するIFCビューアを構築した。

IFCファイルをドロップするだけで即座に3Dモデルとして表示され、IFCタイプ別の要素ツリー、クリックによるプロパティ参照、タイプ別ハイライト、エッジ表示・透過モード、GLBエクスポートに対応する。サーバーへのファイルアップロードは一切不要で、すべてブラウザ内で完結する。

スクリーンショット

IFC Viewer スクリーンショット IFC Viewer スクリーンショット

動画(GIF)

IFC Viewer スクリーンショット

Sample data

サンプルデータは「STEP Tools, Inc.」さんのサイトからお借りしています。
「STEP Tools, Inc.」はCAD・CAM・BIM分野のデータ交換標準規格に特化したソフトウェア開発キット(SDK)およびツールを提供する企業のサイトです。

今回の実装内容

機能・モジュール概要
web-ifc WASM統合IFC C++パーサーのEmscripten WASMビルドをブラウザに組み込み
IFCジオメトリ変換StreamAllMeshes → 頂点/インデックスバッファ → Three.js BufferGeometry
IFCスキーマ自動検出ファイルヘッダからIFC2X3/IFC4/IFC4X3を自動判定
タイプ別要素ツリーIFCWALL、IFCSLAB等のIFCタイプで分類、クリックでタイプ別ハイライト
プロパティ表示メッシュクリックでexpressID・タイプ・属性をパネル表示
エッジ表示EdgesGeometryによる建築図面風のワイヤー表示
透過モード全メッシュを半透明にして構造を確認
GLBエクスポートGLTFExporterでGLBファイルをダウンロード
カメラ自動フレーミング建築スケール対応のバウンディングボックス計算

背景

IFC(Industry Foundation Classes)は建築・土木・設備のBIM(Building Information Modeling)で使用される標準データフォーマット。建物の3Dジオメトリだけでなく、壁・床・柱・窓等の部材タイプ、材質、寸法等のメタデータを含む。

IFCファイルを表示するには専用ソフトウェアが必要だが、web-ifcプロジェクトがIFCパーサーをEmscriptenでWASMビルドしたことで、ブラウザ内でのパース・表示が可能になった。

技術実装の詳細

1. アーキテクチャ

[ ブラウザ ]
│  IFCファイルドロップ → Uint8Array

[ web-ifc WASM ]
│  OpenModel(data) → modelID
│  StreamAllMeshes(modelID, callback)
│  → FlatMesh { expressID, geometries[] }
│    → GetGeometry() → 頂点/インデックスバッファ

[ Three.js BufferGeometry ]
│  positions, normals, indices + IFCカラー/透過度
│  + Matrix4 変換行列適用

[ WebGL描画 ]
   OrbitControls, EdgesGeometry, Raycaster

2. web-ifcの組み込み

web-ifcはEmscriptenビルドのWASMモジュール。web-ifc-api-iife.js(IIFEバンドル)とweb-ifc.wasmの2ファイルで構成される。

IIFEビルドではSetWasmPath()が機能しないため、Init()locateFileハンドラでWASMパスを明示指定する。マルチスレッド版(SharedArrayBuffer必須)はCOOP/COEPヘッダーが必要なため、forceSingleThread: trueで回避。

<script src="/libs/web-ifc-api-iife.js" is:inline></script>
const api = new WebIFC.IfcAPI();
await api.Init((path) => '/libs/' + path, true); // locateFile + forceSingleThread

3. ジオメトリ変換パイプライン

web-ifcのStreamAllMeshesはIFCファイル内の全メッシュをコールバック形式で返す。各FlatMeshには複数のPlacedGeometryが含まれ、それぞれに頂点データ(x,y,z,nx,ny,nz の6 floats/頂点)とインデックスデータ、カラー(RGBA)、変換行列がある。

api.StreamAllMeshes(modelID, (flatMesh) => {
  for (let i = 0; i < flatMesh.geometries.size(); i++) {
    const pg = flatMesh.geometries.get(i);
    const geom = api.GetGeometry(modelID, pg.geometryExpressID);

    // 頂点データ分離 (6 floats → position + normal)
    const vData = api.GetVertexArray(geom.GetVertexData(), geom.GetVertexDataSize());
    const iData = api.GetIndexArray(geom.GetIndexData(), geom.GetIndexDataSize());

    // Three.js BufferGeometry構築
    const bufferGeom = new THREE.BufferGeometry();
    bufferGeom.setAttribute('position', ...);
    bufferGeom.setAttribute('normal', ...);
    bufferGeom.setIndex(...);

    // IFCカラー + 変換行列適用
    const mesh = new THREE.Mesh(bufferGeom, material);
    mesh.applyMatrix4(new THREE.Matrix4().fromArray(pg.flatTransformation));
  }
});

4. IFCタイプ逆引きマップ

web-ifcのGetLineType()はIFCタイプを数値IDで返す。WebIFCオブジェクトにはIFCWALL = 2391406946等の定数が定義されているが、数値→名前の逆引きは用意されていない。起動時に逆引きマップを構築する。

const ifcTypeMap = new Map();
for (const [key, val] of Object.entries(WebIFC)) {
  if (typeof val === 'number' && key.startsWith('IFC')) {
    ifcTypeMap.set(val, key);
  }
}

5. IFCスキーマ自動検出

web-ifcのGetHeaderLine()はバージョンによって動作が不安定なため、IFCファイルの先頭2000バイトからFILE_SCHEMAを正規表現で直接抽出する。

const text = new TextDecoder().decode(data.slice(0, 2000));
const m = text.match(/FILE_SCHEMA\s*\(\s*\(\s*'([^']+)'/i);
if (m) schema = m[1]; // 'IFC4X1', 'IFC2X3', etc.

技術スタック

  • Astro — ページ構築
  • web-ifc v0.0.77 — IFC C++パーサーのEmscripten WASMビルド(IFC2X3/IFC4/IFC4X3対応)
  • Three.js r160 — BufferGeometry, OrbitControls, EdgesGeometry, Raycaster, GLTFExporter
  • vanilla JavaScript — DOM操作、ドラッグ&ドロップ、ファイル処理

更新履歴

  • [v1.0]: web-ifc WASM統合、IFCジオメトリ3D表示、タイプ別要素ツリー、プロパティ表示、エッジ/透過モード、GLBエクスポート。公開。