VRML 2.0ファイルを1つに集約! 配布と共有をスマートにするGo製CLIツール「VRML-Inline-Expander」
はじめに
VRML 2.0(Virtual Reality Modeling Language)で大規模なシーンを管理する際、Inlineノードによる外部参照は非常に便利です。しかし、成果物をGoogle Driveなどで共有する際、参照ファイルがバラバラの状態だと、管理やアップロードの面で課題が生じることがあります。
今回は、これらの課題を解決するためにGo言語で開発した、VRMLのInlineノードを再帰的に解析・埋め込みを行うツール VRML-Inline-Expander を紹介します。
開発の背景:ファイル共有とアップロードの効率化
このツールを作ったきっかけは、VRMLファイルをGoogle Driveにアップロードして他者と共有する実務上の必要性でした。
分割されたファイル構造のままアップロードしようとすると、参照されている多数のサブファイルだけでなく、制作過程で生じた関係のないファイルまで同期対象に含まれてしまい、時間がかかるという問題がありました。
「これ1つを渡せば、どの環境でも正しく表示される」という状態のファイルを作成することで、共有ミスを防ぎ、アップロード時間を短縮することができます。
なぜGo言語でCLIツールを作ったのか
本ツールはGo言語を採用し、実行可能なバイナリ形式のCLIツールとして提供しています。これには以下のメリットがあります。
- 環境構築が不要: Goでビルドされたバイナリ1つで動作するため、実行環境に特定のランタイムをインストールする必要がありません。
- 自動化への組み込みやすさ: 標準入出力を活用したパイプ処理や、シェルスクリプト、CI/CDパイプラインの一部として組み込むのが容易です。
技術的なこだわり:循環参照への安全な対応
外部ファイルを再帰的に読み込む処理では、誤って自分自身や親ファイルを呼び出してしまう「無限ループ」のリスクが常に伴います。本ツールでは、探索中のパスの履歴(祖先リスト)を管理することで、これを確実に防いでいます。
1. 「祖先」を追跡するAncestorSet
Goの map[string]struct{} を利用して、現在パースしているファイルの「親・祖父母...」にあたる絶対パスを記録する AncestorSet を実装しました。
type AncestorSet struct {
fileAbsPaths map[string]struct{}
}
// 既に祖先に含まれている(=循環している)かチェック
func (as AncestorSet) Contain(absPath string) bool {
_, exists := as.fileAbsPaths[absPath]
return exists
}
2. イミュータブル(不変)な設計による再帰の安全性
こだわったのは、Add メソッドの挙動です。既存のセットを直接書き換えるのではなく、常にコピーを作成して新しいセットを返す設計にしています。
func (as AncestorSet) Add(absPath string) AncestorSet {
newPaths := make(map[string]struct{}, len(as.fileAbsPaths)+1)
maps.Copy(newPaths, as.fileAbsPaths) // 現在の階層までの履歴をコピー
newPaths[absPath] = struct{}{}
return AncestorSet{fileAbsPaths: newPaths}
}
VRMLファイル内に複数の Inline ノードがある場合、探索はツリー状に分岐します。この設計により、ある分岐での探索履歴が他の分岐に影響を与える(副作用を起こす)ことなく、各パスが自身の「祖先」だけを正しく把握できるようになっています。
使い方
Go環境があれば、数コマンドで利用可能です。
インストールと実行
git clone https://github.com/akisatoon1/VRML-Inline-Expander.git
cd VRML-Inline-Expander
go build -o vrml-expander
# インライン化を実行してファイルに出力
./vrml-expander input.wrl > output_merged.wrl
まとめ
「VRML-Inline-Expander」を活用することで、複雑な構成のVRMLデータを、ポータビリティの高い1つのファイルに集約できます。Google Driveでの共有作業を効率化したい方や、成果物の配布プロセスをシンプルにしたい方は、ぜひ試してみてください。