こんにちは。
株式会社Oh my teethでテックリードをやっているTerukiです。
前回の記事から少し間が空いてしまいましたが2本目の記事を書いていきます
TL;DR
- STLをDracoに変換するとSTLファイルのサイズがだいたい10分の1ほどにできる
- この記事を読めばSTLをDracoで圧縮したファイルを作れる
- Oh my teethの無料歯型スキャン予約時にプロモーションコード「QiitaSTL」を入力するとスキャンしたSTLファイルが貰える
概要
DracoというGoogleが開発している3Dモデルのファイル形式があります。
STLファイルをDracoに変換するとファイルサイズがだいたい10分の1ほどにできます。
Webで3Dビューアを実装する際、STLのままロードするとファイルサイズが大きくなりモバイル回線だと表示される前にユーザーが離脱してしまいます。
Oh my teethでは前回の記事の概要の通り歯型の3Dデータをレンダリングしていますが、歯型のSTLが上下顎合わせると30MB近くになるためせっかく作ったビューアも触られない、そもそも歯型が表示されることに気付いてもらえないなどが課題でした。
この記事ではSTLをDracoに変換する部分とThree.jsでレンダリングするところまで説明できればと思います。
準備するもの
- NodeJS
- 適当なエディタ
前回に引き続き基本TypeScriptでやっていきます。
やってみる (STL→Draco変換)
Three.jsでDracoをレンダリングしようにもまずは既存のSTLを変換できないとお話になりません。
STLをDracoに変換するにはDracoのリポジトリにあるコードを自前でビルドする必要があります。
公式でバイナリを配布しているか探してみましたが私は見つけられませんでした。
公式に各環境に合わせたビルド手順が書かれているので細かいことは公式に投げますが、この記事ではまっさらなWSL Ubuntu 22.04でやってみます。
ファイル準備
mkdir ~/work
cd ~/work
git clone https://github.com/google/draco.git
cd draco
mkdir out && cd out
必要なツールをインストール
sudo apt-get update
sudo apt-get install cmake g++
プロジェクトファイル作成
cmake ../
ビルド
make
※make -j 12などオプションをつけるとパラレルでビルドするので速くなります。12の部分は環境に合わせて変更ください
ここまでくるとカレントディレクトリにdraco_encoder
とdraco_decoder
のシンボリックリンクができていると思います。
これでエンコーダーの準備ができたので前回の記事も使ったStanford_Bunnyを変換してみます。
wget https://upload.wikimedia.org/wikipedia/commons/4/43/Stanford_Bunny.stl
./draco_encoder -i Stanford_Bunny.stl -o bunny.drc
出典: https://commons.wikimedia.org/wiki/File:Stanford_Bunny.stl
私の環境では下記のような結果になりました。
mrtska@Vega:~/work/draco/out$ ls -lh Stanford_Bunny.stl bunny.drc
-rw-r--r-- 1 mrtska mrtska 5.4M Jan 24 2020 Stanford_Bunny.stl
-rw-r--r-- 1 mrtska mrtska 491K Mar 26 02:03 bunny.drc
5.4Mが0.5Mほどまで小さくなっているのが分かります。すごい!
やってみる (Three.jsでDracoをレンダリング)
stlをdrcに変換することができました。
ただ、変換してサイズが小さくなってもレンダリングできなければ何の意味もありません。
前回の記事で使ったリポジトリを拝借して続きを開発してみます。
git clone https://github.com/ohmyteeth/threejs-stl-sample.git
と言っても実はものすごく簡単でThree.js側はSTLLoaderをDRACOLoaderに変えるだけです。
このDRACOLoaderはWebAssemblyのDracoデコーダーを使ってデコードするため、別途デコーダーのwasmとそのラッパーを用意してあげます。
このラッパーとwasmはThree.jsのパッケージの中に入っているのでここではsrc
配下にコピーして使います。
実運用ではCDNか何かに置いておくのが良さそうです。
cp node_modules/three/examples/jsm/libs/draco/draco_decoder.wasm src/
cp node_modules/three/examples/jsm/libs/draco/draco_wasm_wrapper.js src/
main.ts
の修正
import * as THREE from 'three';
-import { STLLoader } from 'three/examples/jsm/loaders/STLLoader';
+import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
-// STLファイルをロードしてレンダリング
-const stlLoader = new STLLoader();
-stlLoader.load('./Stanford_Bunny.stl', (geometry) => {
+// DRCファイルをロードしてレンダリング
+const dracoLoader = new DRACOLoader();
+dracoLoader.setDecoderPath('/src/');
+
+dracoLoader.load('./bunny.drc', (geometry) => {
const material = new THREE.MeshPhongMaterial({
color: 0xFFFFFF
});
これで準備はできました。npm run dev
して見てみましょう。
前回の記事の最後の部分と比較してみても目視では全然分かりませんね!
最終形のコードはこちら:
https://github.com/ohmyteeth/threejs-drc-sample/blob/main/src/main.ts
歯型STLプレゼントキャンペーン
前回の記事と同様、歯型STLプレゼントキャンペーンのご紹介です。
Oh my teethはマウスピース矯正ブランドの1つです。
詳細なサービスの説明は公式サイトにお任せしますが、tech系の内容については以前Techableに寄稿したこちらの記事が面白いかもしれません。
また、マウスピース矯正に興味がある方に無料歯型スキャンでスキャンした歯型のSTLとDRCをお渡しします
スキャン後に私から上顎と下顎のSTLファイルをお渡しします!
上記予約フォームのリンクか、プロモーションコード欄に「QiitaSTL」と入力してご予約ください。
歯医者だけど歯医者っぽくないtech感ある体験ができるので気軽にお越しいただければと思っています。
おわりに
前回に続いてThree.jsの記事をお送りしました。
Oh my teethでは未来の歯科体験を実現していくためにテクノロジーに力を入れているのでこういった発信をどんどんしていけたらと思っています。
次回はまた違った観点で記事にできたらと思っています。
ではでは!