2025年10月31日金曜日

3D Gaussian SplatsビューワーをAPEXアプリケーションに組み込む

衛星画像から3Dの都市シーンを生成するSkeyfall-GSというプロジェクトがあります。詳しい内容は理解できませんが、衛星画像と生成AIだけで3Dの都市シーンを生成するという仕組みのようです。最終的に生成するデータはPLY(Polygon File Format)であり、このPLYデータを3D Gaussian Splatsビューワーを使用して、ブラウザに表示しています。

Skyfall-GSでは3D Gaussian SplatsビューワーとしてGaussianSplats3Dを使用しています。今回はこのGaussianSplats3Dビューワーを、APEXアプリケーションに組み込んでみます。

作成したAPEXアプリケーションは以下のように動作します。Oracle Databaseと3Dビューワーを組み合わせる方法の確認のためにアプリケーションを作成していて、実用的な3Dビューワーの作成を目的とはしていません。


以下よりAPEXアプリケーションの作成手順を紹介します。

最初にクイックSQLを使用し、PLYファイルを保存する表SPLAT_FILESを作成します。クイックSQLには以下を記述します。
splat_files
    image file
レビューおよび実行を行い、ガイドに従って最終的に表SPLAT_FILESを作成します。


空のAPEXアプリケーションを作成します。名前は3D Gaussian Splats Viewerとします。


アプリケーションが作成されます。表SPLAT_FILESに保存したファイルの一覧表示と、ファイルのアップロードを行なうページを作成します。

ページの作成をクリックします。


対話モード・レポートを選択します。


レポートのページの名前はFilesとし、フォーム・ページを含めるをオンにします。ファイルのダウンロードURLを生成する際にページ番号を含むページ・アイテム名を参照するため、フォーム・ページ番号は必ず3にします。フォーム・ページ名はFileとします。

データ・ソースの表/ビューの名前としてSPLAT_FILESを選択し、次へ進みます。


主キー列1にID(Number)を選択します。

ページの作成をクリックします。


対話モード・レポートとフォームのページが作成されます。

ページ・デザイナで対話モード・レポートのページを開き、列IMAGEのBLOB属性を設定します。

MIMEタイプ列にIMAGE_MIMETYPE、ファイル名列にIMAGE_FILENAME、最終更新列にIMAGE_LASTUPD、文字セット列にIMAGE_CHARSETを設定します。


ページ・デザイナでフォームのページを開き、ページ・アイテムP3_IMAGEのストレージを、先ほどのレポート列のBLOB属性と同様に設定します。


以上で簡単なファイル管理を行なうページが作成できました。

このページを使用して表SPLAT_FILESにアップロードするデータを準備します。

Skyfall-GSのページを開き、3DGS PLY Filesのページに移動します。


Google Driversが開くので、興味のあるPLYファイルをいくつかダウンロードします。


APEXアプリケーションを実行し、Filesのページを開きます。

作成ボタンをクリックし、ファイルをアップロードするドロワーを開きます。


Imageに先ほどダウンロードしたPLYファイルを選択し、作成をクリックします。


レポートのページに戻り、アップロードされたファイルが一覧に表示されます。


複数のPLYファイルをダウンロードしている場合、アップロードを繰り返します。


以上で表示するデータの準備ができました。

3Dビューワーはホーム・ページに実装します。ページ・デザイナでホーム・ページを開きます。

表示するファイルを選択するページ・アイテムを作成します。

識別の名前はP1_FILE、タイプは選択リスト、ラベルはFileとします。

LOVのタイプにSQL問合せを選択し、SQL問合せとして以下を記述します。

select image_filename d, image_filename r from splat_files


表SPLAT_FILESからファイルを取り出すURLを保存するページ・アイテムとして、P1_URLを作成します。タイプは本来非表示にすべきですが、デバッグのためテキスト・フィールドを選択します。


選択したファイルを表示するボタンDRAWを作成します。動作のアクションはページの送信です。外観のホットはオン、テンプレート・オプションのWidthにStretchを指定します。


3D Gaussian Splatsビュワーの表示領域となるリージョンを作成します。

識別の名前は3D Gaussian Splats Viewer、タイプは静的コンテンツとします。外観のテンプレート・オプションのRemove Body Paddingにチェックを入れ、リージョンいっぱいに3D画像が表示されるようにします。

ソースのHTMLコードに以下を記述します。3D Gaussian Splatsビューワーは、canvas-containerを対象として初期化します。

<div id="canvas-container"></div>


以上で、ページ上のコンポーネントの配置は完了です。

ボタンDRAWをクリックしたときに、ファイル名からダウンロードURLを生成するプロセスを作成します。

識別の名前はGet URLとし、ソースのPL/SQLコードとして以下を記述します。

サーバー側の条件のボタン押下時にDRAWを選択します。


3D Gaussian Splatsビューワーの本体の処理と言えるJavaScriptのコードを記述したファイルを、静的アプリケーション・ファイルとして作成します。ファイル名はapp.jsとし、以下の内容を記述します。


ホーム・ページに3Dビューワーを組み込みます。

ページ・プロパティのJavaScriptのファイルURLに以下を記述し、静的アプリケーション・ファイルのapp.jsを、ページにロードします。

[module]#APP_FILES#app#MIN#.js

CSSのインラインに以下を記述し、3Dビューワーの描画領域を設定します。
#canvas-container {
    flex: 1;
    width: 100%;
    height: 800px;
    position: relative;
}
app.jsの中で参照しているthree.jsおよびgaussian-splats-3d.jsのimportmapを設定します。

HTMLヘッダーに以下を記述します。



あまり深く理由については調べていませんが、3D Gaussian Splats Viewerのライブラリが表示するデータをデータベースから読み込むと、CORSに関するエラーが発生します。

そのため、アプリケーション定義のセキュリティに含まれる、ブラウザ・セキュリティのセクションのHTTPレスポンス・ヘッダーに、以下の2つのヘッダーを設定しています。

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp


以上でAPEXアプリケーションは完成です。アプリケーションを実行すると、記事の先頭のGIF動画のように動作します。

今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/3d-gaussian-splats-viewer.zip

Oracle APEXのアプリケーション作成の参考になれば幸いです。

完