three.jsのIFCLoaderをアップデートする

three.jsのIFCLoaderは、本家のifc.jsで管理されているweb-ifc-threeに比べてアップデートが遅いため、本家の更新を利用できるまで時間がかかる。あちこちにファイルが分散しているので、集結して動作させる。ifc.jsだけバージョンを上げてみた時のメモ。

## 動作環境
* macOS 13.1
* node v16.18.0
* yarn 1.22.17
2023/2/11現在の最新リポジトリを使用
* [three.js](https://github.com/mrdoob/three.js/), r149
* [web-ifc](https://github.com/IFCjs/web-ifc), 28f317d
* [web-ifc-three](https://github.com/IFCjs/web-ifc-three), fefec08
    * ["three": "0.149"に対応している様子](https://github.com/IFCjs/web-ifc-three/blob/fefec08bc89fd07b1fd36874c15db53f493989bd/web-ifc-three/package.json#L66)

## 1. three.js
three.jsのリポジトリを取得すると、buildフォルダに既にビルド(rollup)済みのファイルが置いてある。ここではthree.module.jsを使う。

* build/three.js
    * オリジナルのjsファイル。デバッグ用。
* build/three.min.js
    * オリジナルのjsファイルのサイズを小さくしたバージョン。配布用。
* build/three.cjs
    * CommonJSバージョン。node.jsで使用する。
* build/three.module.js
    * ES modules (新しいプロジェクトではこれを使えば良い)

IFC関連のファイルは以下の通り。これらを置き換える。
* examples/jsm/loaders/IFCLoader.js
* examples/jsm/loaders/ifc/web-ifc-api.js
* examples/jsm/loaders/ifc/web-ifc.wasm

## 2. web-ifc
ifc.jsのコア部分。wasmを生成する。wasmファイルは `npm install web-ifc` で取得するか、githubで取得した後ビルドする。ここではcloneしてbuildする。wasmファイルはWebAssemblyで定義された仮想マシン上の実行ファイル（仮想命令セット）であり、Webブラウザなど[WebAssembly対応環境](https://caniuse.com/?search=wasm)であれば、マルチプラットフォームで動作させることができる。

```zsh: zsh
git clone https://github.com/IFCjs/web-ifc.git
cd web-ifc
yarn install
yarn build-release
```
ここまでで、distフォルダに以下を含むファイルが生成される。
* web-ifc-api.js
* web-ifc.wasm

## 3. web-ifc-three
three.jsでIFCファイルを読み込むためのIFCLoaderを取得する。こちらも `npm install web-ifc-three` で取得できるが、ここではcloneして取得する。

```zsh: zsh
git clone https://github.com/IFCjs/web-ifc-three.git
cd web-ifc-three
yarn install
yarn build
```
すると、./web-ifc-three/dist/ フォルダに以下を含むファイルが出力される。
* IFCLoader.js


## 4. three.jsのIFCLoaderを差し替え
ステップ1で記載した通り、以下のファイルをステップ２、３で生成したファイルに置き換える。

* examples/jsm/loaders/IFCLoader.js
* examples/jsm/loaders/ifc/web-ifc-api.js
* examples/jsm/loaders/ifc/web-ifc.wasm

three.jsにコピーする際にpathが変更されるため、 IFCLoader.js の以下の部分を変更する。

オリジナル
```JavaScript: web-ifc-three/web-ifc-three/dist/IFCLoader.js
import * as WebIFC from 'web-ifc';
...
import { mergeBufferGeometries } from 'three/examples/jsm/utils/BufferGeometryUtils';
```
変更後
```JavaScript: web-ifc-three/web-ifc-three/dist/IFCLoader.js
import * as WebIFC from 'web-ifc';
...
import { mergeBufferGeometries } from '../utils/BufferGeometryUtils.js';
```
また、`web-ifc`部分は`./js/three/three.module.js`に置き換えるか、importmapで追加してから、必要なjsファイルを読み込む。

## 5. IFCファイルの読み込みサンプル
IFCファイルを読み込むサンプルにはifc.jsの[Hello World](https://ifcjs.github.io/info/docs/Guide/web-ifc/Tutorials/Hello%20world/)を利用する。

`web-ifc`部分をimportmapで解決する場合は、以下のように記述を追加してから、IFCLoaderを読み込むJSファイル(js/main.js)をロードする。

```html: index.html
<script type="importmap">
        {
            "imports": {
                "three": "./js/three/three.module.js",
                "web-ifc": "./js/three/examples/jsm/loaders/ifc/web-ifc-api.js"
            }
        }
</script>
<script src="js/main.js" type="module"></script>
```

IFCLoader使用時は[wasmファイルを指定](https://github.com/shohara/ifcloader-sample/blob/main/js/main.js#L15
)する。
```Javascript:js/main.js
const ifcLoader = new IFCLoader();
await ifcLoader.ifcManager.setWasmPath( './js/three/examples/jsm/loaders/ifc/' )
```

以上で差し替えが完了して。新しいifc.jsでIFCファイルを読み込めるようになった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123458/95386085-bb3f-0a30-366e-bd46d14fcf62.png)

最終系のコードは[github](https://github.com/shohara/ifcloader-sample)にあり、[github pages](https://shohara.github.io/ifcloader-sample/)でアクセスできる。