株式会社センシンロボティクス(以下、長いのでSRと記載します)でエンジニアをしております、@no13 です。本記事は、SRの2025年アドベントカレンダー4日目の記事です。私たちのチームが直面した課題と、それを乗り越えるために取り組んだ解決策についてご紹介します!
用語解説と3D Tilesの構造
本記事で扱う主な専門用語と、データ構造を先に解説します。
用語解説
- DJI Terra: DJI社が提供する、ドローン画像から3Dモデルや点群を生成するためのソフトウェア。
- Cesium: 大規模な3D地理空間データをブラウザ上で可視化するためのオープンソースのJavaScriptライブラリ(CesiumJS)。
- 3D Tiles: 大容量の3D地理空間データを効率的にストリーミング・レンダリングするためのオープン規格。
- b3DM/GLB: 3D Tilesのデータ構造を構成する主要なバイナリフォーマット。
3D Tilesの構造図
以下は、3D Tilesの構造図です。b3DMやBufferViewがどのように関連しているかを示しており、以降で議論する課題がどのデータ構造に関連するかを視覚的に理解できます。
背景:大規模3DデータにおけるDJI TerraとCesiumの課題
SRが取り組む社会インフラや重厚長大産業のDXにおいて、大規模な3D地理空間データ(デジタルツイン)の可視化は必須です。このデータ活用のために用いられる3D Tilesは、Cesiumなどで使用されるオープン規格ですが、DJI Terraで生成されるデータにはしばしばエラーや非互換性が含まれていました。
これにより、データの表示や操作に問題が生じることがあります。主な課題は以下の3点に集約されます。
| 問題の種類 | 概要 | 技術的な影響 |
|---|---|---|
| WebP画像の非互換性 | CesiumJSはglTF拡張(EXT_texture_webp)経由でWebPテクスチャをサポートしていますが、一部ブラウザやランタイムでの互換性の課題が残るため、テクスチャが正しく表示されないことがありました。 | テクスチャが正しく表示されない。 |
| バイナリアライメントの問題 | b3DMのバイナリデータが8バイト境界に揃っていない。 | Cesiumでの読み込み時にエラーが発生する(DeveloperErrorの原因)。 |
| BufferViewの競合 | GLBファイル内のBufferView定義に競合や矛盾がある。 | モデルの一部が欠けたり、レンダリングが停止したりする。 |
これらの課題を根本的に解決し、3D Tilesデータの品質を確保するために、私たちは、これらの課題に対応するためのデータ修復ツールを開発しました。
ステップ1:致命的なDeveloperErrorとの戦い(バージョンアップによる解決)
このセクションでは、当初直面したクリティカルなレンダリングエラー(DeveloperError)の解決に焦点を当てます。このエラーの解決こそが、その後のデータ修復ツール開発の前提となりました。
3D Tilesデータを操作中、特にズームイン・ズームアウトや視点移動を繰り返した際に、Cesiumのレンダリングが停止し、以下のエラーダイアログが表示される問題に直面しました。
エラー内容
An error occurred while rendering. Rendering has stopped.
DeveloperError: sourceOffset + length must be less than the buffers size.
このエラーは、Cesiumの内部処理、具体的にはバッファサイズに関する不正な参照が原因で発生していました。ダイアログを閉じた後もCesium内での操作は完全に停止し、ページをリロードしない限り復旧できない状態になります。
対策アプローチの試行錯誤
1. エラーイベントの捕捉と抑止(失敗)
まず試みたのは、エラーを外部から捕捉してレンダリングを続行させるアプローチです。
// レンダリングエラー時の抑止
this.viewer.scene.renderError.addEventListener((scene: any, error: any) => {
console.warn('Render error suppressed:', error);
// レンダリング停止フラグを強制的にリセット
scene._renderError = false;
});
結果: この方法では、Cesium内部で発生するクリティカルなDeveloperErrorを完全に捕捉することはできず、根本的な解決には至りませんでした。このエラーはCesium内部で握りつぶされ、外部へthrowされていないことが原因と考えられます。データ構造の不正に起因するエラーは、外部からイベントで制御するだけでは不十分でした。
2. Cesiumのバージョンアップ(ハマったポイントを含む試行)
致命的なDeveloperErrorについて、発生当時、原因調査および情報収集を行った結果、同様のエラーメッセージに対する修正を含むCesiumのPull Request(Fix issue with pickModel for interleaved buffers by ggetz · Pull Request #11842 · CesiumGS/cesium)が存在することを確認しました。
-
対象バージョン:
cesium@1.115.0に修正が含まれていると推測。
このバージョンへの部分的なアップグレードを試みたところ、以下のエラーが発生し、検証が一時中断しました。
~~.ts:162 RequestErrorEvent2 {statusCode: 401, response: '{"code":"INVALID_TOKEN","message":"Invalid access token"}', responseHeaders: {…}}
この401エラーは、環境由来の認証エラーであり、本質的な3D Tilesデータのエラーではないと判断。細かくバージョンを追うことを避け、一気に最新バージョンへの移行を試みました。
最新バージョンへのアップグレード(解決)
結果: Cesiumを当時の最新バージョンである1.135にアップグレードしたところ、問題のDeveloperErrorが解消されました。点群データも正常に表示され、レンダリングエラーは発生しなくなりました。
教訓: 細かいバージョンを試すよりも、まず最新バージョンにアップグレードすることが、多くの既知のバグや内部的な競合を解決する上で最も有効な手段であると再認識しました。
ステップ2:データ修復ツールによる残存課題の解決と品質向上
バージョンアップによってレンダリングエラーは解消されましたが、根本的なデータ品質の問題(WebP非互換、BufferView競合、アライメント不正など)は残ります。これらの残存課題を解決し、データの信頼性を高めるために、私たちはデータ修復ツールを開発しました。
ツール化の目的
| 目的 | 詳細 |
|---|---|
| 効率化/時間短縮 | 複数のb3DMファイルを一括で自動処理することで、手動による修正に伴う時間コストと作業負荷を大幅に削減。 |
| 品質向上 | 修復後のデータを定量的にバリデーションし、エラーを削減。 |
| 汎用性 | 公式ツールと独自スクリプトを組み合わせ、多様なエラーに対応。 |
データ修復ツールの概要と構成要素
このツールは、私たちが開発した自作スクリプトと、Cesium公式のツール群を連携させる形で構成しています。
| ツール分類 | ツール名/機能名 | 主な役割 |
|---|---|---|
| Cesium公式ツール | 3d-tiles-validator | b3DMファイルの構造的な問題を検出、レポート生成。 |
| 3d-tiles-tools | バイナリアライメントの問題を修正。 | |
| 自作スクリプト | WebP画像変換スクリプト | WebPをPNG/JPEGに変換し、Cesiumでの表示を可能にする。(Python 3.x, sharp使用) |
| BufferView競合解消スクリプト | GLB内のBufferView定義の分離と修正。(Python 3.x使用) |
注意: このツールは社内専用であり、現在公開されていません。
データ修復ツールの内部タスクの定義
データ修復ツール内部で定義された主要な処理名(タスク名)は以下の通りです。これらのタスクは、公式ツールや独自スクリプトの機能を抽象化し、複数のb3DMファイルを効率的に処理するために使用します。
-
validate:
3d-tiles-validatorの機能を呼び出し、B3DMファイルの構造的な問題を検出し、エラー内容をレポートします。 -
update-alignment:
3d-tiles-toolsの同名の機能を呼び出し、バイナリアライメントの問題を修正します。 - convert-webp: WebP画像変換スクリプトを実行し、WebP形式の画像をPNGまたはJPEG形式に変換します。
- fix-bufferview: BufferView競合解消スクリプトを実行し、GLB内のBufferView定義の分離と修正を行います。
エラーと対応ツールの対応表
バリデーションレポート(3d-tiles-validator出力)に基づき、エラーと修復ツールの対応関係を明確にしました。
| エラー内容 | エラータイプ(抜粋例) | 対応ツール | 修正内容 |
|---|---|---|---|
| Feature Tableの8バイトアライメント不足 | BINARY_INVALID_ALIGNMENT |
3d-tiles-tools |
8バイト境界への強制アライメント修正 |
| テクスチャがWebP形式である |
CONTENT_VALIDATION_ERROR (MIME type 'image/webp') |
WebP画像変換スクリプト | WebPをPNG/JPEGに変換 |
| BufferViewの定義に競合がある | Override of previously set bufferView target or usage |
BufferView競合解消スクリプト | BufferViewの分離と修正 |
| Length of 0x004e4942 chunk is not aligned to 4-byte boundaries | 未特定(要調査) | 要調査 | 今回のメイン課題ではなかったため保留 |
修復ツールの実行結果:定量的な品質向上
修復ツールを実行した結果、データ品質が大幅に改善されました。
| 項目 | 修復前 | 修復後 | 改善効果 |
|---|---|---|---|
| エラー総件数 | 32,978件 | 2,247件 | 約93%削減 |
| 警告件数 | 7,765件 | 98件 | 大幅削減 |
| 主な解消エラー |
BINARY_INVALID_ALIGNMENT: 10,444件 |
0件 | 完全解消 |
特にレンダリングエラーの要因となっていたバイナリアライメントエラーが完全に解消され、3D Tilesデータの信頼性が大幅に向上しました。
-
修復後に残ったエラー(2,247件)について:
残存するエラーの多くは、幾何学的な微細な不整合に関するものであり、Cesium上でのモデル表示に致命的な影響を与えないレベルであることを確認しました。
まとめ:解決の鍵は「バージョンアップ」と「データ修復」の両輪
本プロジェクトを通じて、特定のツールで生成された3D TilesデータをCesium上で安定的に利用するための解決法を確立しました。
-
致命的なレンダリングエラーの解決:
DeveloperErrorは、Cesiumの最新バージョンへのアップグレードによって解消されました。 -
データ品質の向上と互換性の確保:
修復ツールにより、WebP非互換やアライメントの問題といった根本的なデータ構造の不正を修正し、データの信頼性を大幅に向上させました。
ハマったポイントと教訓
- イベント捕捉の限界: クリティカルなエラーは、単なるイベントリスナーでの抑止では解決できず、データ構造の修正かレンダリングエンジンの改善が必要不可欠でした。
- ファイル修復だけでは不十分なケース: データ構造を修正しても、当時のCesiumバージョンに内在するバグがエラーを再発させていました。バージョンアップとデータ修復の両方を組み合わせる柔軟な対応が求められました。
- 処理時間の課題: 修復処理は、スペックにも依存しますが、修復パターン一つあたり、1ファイルにつき1〜2秒程度の処理時間を要します。特に最大規模のデータセット(単一モデルで約4GB)を処理した際には、完了までに2時間近くかかりました。大規模データセットではトータルの処理時間が膨大になるため、ツールの一括実行機能と高速化の必要性を痛感しました。
- 教訓: 複雑なレンダリングエラーに遭遇した際は、まず最新バージョンに移行することが最善策であり、ファイル修復はその後のデータ品質を底上げするために必須であると痛感しました。
修復ツールの処理フロー図
以下は、修復ツールの処理フロー図です。公式ツールと自作スクリプトがどのように連携してデータを修復するかを示しています。
補足: 修復の順序は非常に重要です。独自ツールでの修復(WebP変換やBufferView競合解消)を先に行い、その後に公式ツールのupdate-alignmentを実行する必要があります。逆の順序で処理を行うと、別のエラーが発生したり、修復したはずのエラーが復活することがあります。
これらの技術的な知見とツール開発の経験は、当社のデジタルツイン化プロジェクトにおけるデータ活用の基盤となっています。
