ファイルを作成したバージョンを判別してBlenderを起動するWindowsバッチファイル
失われた互換性を求めて
Blenderはバージョン2.80になってそれ以前のバージョンの.blendファイルとの互換性がかなり失われた。そのため、バージョン2.7系とバージョン2.80の両方をインストールして共存させ、使い分けている人は多いようだ。
しかし、作成したバージョンと異なる.blendファイルをうっかり開いてしまう事故は起こりうる(いや、筆者だけか?)。
ファイルのバージョンを判別して起動できないものか……と考えていたら、BusyBoxというプログラムを使用したバッチファイルで割と簡単にできたので報告する。
BusyBoxの説明はWikipediaのBusyBoxの項目に詳しく書いてあるので、ご存じない方は参照していただきたい。一言でいえば、UNIXでよく使われるコマンドを一つにまとめたプログラムだ。インストールも不要で、パスの通ったフォルダにコピーするだけでいい。この記事では、busybox-w32で配布されているWindows用の64ビット版のbusybox64.exeを使用しているが、32ビット版のbusybox.exeでも問題ない。
どうやってバージョンを判別しているのか
バージョンの異なる.blendファイルをバイナリダンプして先頭の2行を表示させるとこうなる。
>busybox64 hexdump -Cv v280.blend | busybox64 head -n 2 00000000 42 4c 45 4e 44 45 52 2d 76 32 38 30 52 45 4e 44 |BLENDER-v280REND| 00000010 48 00 00 00 b0 e3 9f 33 48 00 00 00 00 00 00 00 |H......3H.......| >busybox64 hexdump -Cv v279b.blend | busybox64 head -n 2 00000000 42 4c 45 4e 44 45 52 2d 76 32 37 39 52 45 4e 44 |BLENDER-v279REND| 00000010 48 00 00 00 10 e5 9f 0b 42 00 00 00 00 00 00 00 |H.......B.......| >busybox64 hexdump -Cv v272.blend | busybox64 head -n 2 00000000 42 4c 45 4e 44 45 52 5f 76 32 37 32 52 45 4e 44 |BLENDER_v272REND| 00000010 48 00 00 00 ac e6 26 00 00 00 00 00 01 00 00 00 |H.....&.........| >busybox64 hexdump -Cv v269.blend | busybox64 head -n 2 00000000 42 4c 45 4e 44 45 52 5f 76 32 36 39 52 45 4e 44 |BLENDER_v269REND| 00000010 48 00 00 00 04 dd d6 bf 00 00 00 00 01 00 00 00 |H...............|
上から順に2.80、2.79b、2.72、2.69のファイルだ(もっと古いバージョンのファイルは、持っていないので調べていない)。
「BLENDER-v2**RENDH」という形式で、バージョン番号が文字列として埋め込まれている。古いバージョンだとアンダースコアを使用しているが、2.7xのどこかの時点でなぜかハイフンに変わったようだ。
ただし、Blenderはファイル保存時に「Compress (ファイルを圧縮)」にチェックを入れると、.blendファイルを圧縮するので、この文字列は検出できない。しかし、.blendファイルを丸ごとgzipで圧縮するという単純な方法なので、BusyBoxのgunzipコマンドで展開すればいい。
バージョン判別起動バッチファイル
先頭の11バイトを調べれば作成したバージョンがわかることが確認できたので、以下のバッチファイルを書いた。使用するには、BusyBoxのWindows版をパスの通ったフォルダに置いておく必要がある。
【2020/12/20 追記】以下のバッチファイルは一年以上前に書いたものだ。2.9系も加えて、現時点のBlenderのバージョンにあわせて書き直したので、この記事の最後に置いておく。
@echo off setlocal enabledelayedexpansion if /I "%~x1" NEQ ".blend" exit /B chcp 65001 set BLENDER_28=E:\blender-2.80-windows64\blender.exe set BLENDER_27=E:\blender-2.79b-windows64\blender.exe REM set PYTHONDONTWRITEBYTECODE=1 for /F "usebackq" %%A in (`busybox64 head -c 11 "%1"`) do set BLEND_HEAD=%%A if "!BLEND_HEAD!" == "BLENDER-v28" ( "%BLENDER_28%" "%1" ) else if "!BLEND_HEAD:_=-!" == "BLENDER-v27" ( "%BLENDER_27%" "%1" ) else ( for /F "usebackq" %%A in (`busybox64 gunzip -c "%1" ^| busybox64 head -c 11`) do set BLEND_HEAD=%%A if "!BLEND_HEAD!" == "BLENDER-v28" ( "%BLENDER_28%" "%1" ) else if "!BLEND_HEAD:_=-!" == "BLENDER-v27" ( "%BLENDER_27%" "%1" ) ) endlocal
このバッチファイルに.blendファイルをドラッグ&ドロップすると、2.80か2.79bかどちらかのBlenderが起動しファイルを開く。高機能なファイラーと組み合わせればもっと便利に使えるだろう1。上述したようにBusyBoxが必要なので、Windows版のBusyBoxについて詳しく知りたい場合は「windows busybox」などと検索していただきたい。
環境に合わせて書き換える必要のある2行
環境に合わせて書き換える必要があるのは5~6行目。
set BLENDER_28=E:\blender-2.80-windows64\blender.exe set BLENDER_27=E:\blender-2.79b-windows64\blender.exe
筆者はZIP版を外付けのEドライブにインストールしているのでこうなっている。
set BLENDER_28= set BLENDER_27=
の各行の後には、各バージョンのblender.exeをフルパスで記述する。例えば、2.80が C:\Program Files\Blender Foundation\Blender\blender.exe にあるとしたら、
set BLENDER_28=C:\Program Files\Blender Foundation\Blender\blender.exe
となる。同様に、2.7系列もset BLENDER_27=に続けてフルパスで
set BLENDER_27=ドライブ名:\(…中略…)\blender.exe
と記述する。
2.7よりも前のバージョンには未対応
2.7より以前のバージョンは無視することにしたので、開けない。2.6xやそれ以前のバージョンのファイルを2.79bなどの2.7系で開けるかどうがわからなかったからだ(開けたとしても使えない機能などがあるかも?)。「blender backward compatibility」などと検索してみても、単発の質疑応答はあるものの、まとまった資料は見つからなかった。
公式で用意してくれていたら安心
このバッチファイルのような機能にはそれなりに需要があると思う。Blenderの開発チームなら後方互換性に関して把握しているだろう2。であれば、こういったプログラムを提供するのは容易なはずだ。公式に同梱されるようになれば誰もが安心して使えるので、そうしてもらえるといいと思う。
2020/12/20 追記(2.8系と2.9系の最新のBlenderのバージョンも判別して起動する)
現時点での最新バージョンにあわせて書き直したバッチファイルは下の通り。2.9系も加えて三つのバージョンを起動し分けるようになっている。また、ファイル名にスペースが含まれていると起動しなかったのを修正した。5~7行目は自分の環境に合わせて書き換える必要がある(以前と同じ)。該当するバージョンのBlenderがインストールされていなければ何もしないで終了する。
@echo off setlocal enabledelayedexpansion if /I "%~x1" NEQ ".blend" exit /B chcp 65001 set BLENDER_29=E:\blender-2.91.0-windows64\blender.exe REM 2.8系のファイルも2.9系で開くなら下(↓)の行の「BLENDER_28=」の後ろに上(↑)と同じblender.exeを指定すればいい set BLENDER_28=E:\blender-2.83.10-windows64\blender.exe set BLENDER_27=E:\blender-2.79b-windows64\blender.exe for /F "usebackq" %%A in (`busybox64 head -c 11 "%~1"`) do set BLEND_HEAD=%%A set BLEND_HEAD=!BLEND_HEAD:_=-! set BLEND_HEAD=!BLEND_HEAD:V=v! if "!BLEND_HEAD!" == "BLENDER-v29" ( if not exist "%BLENDER_29%" exit "%BLENDER_29%" "%~1" ) else if "!BLEND_HEAD!" == "BLENDER-v28" ( if not exist "%BLENDER_28%" exit "%BLENDER_28%" "%~1" ) else if "!BLEND_HEAD!" == "BLENDER-v27" ( if not exist "%BLENDER_27%" exit "%BLENDER_27%" "%~1" ) else ( for /F "usebackq" %%A in (`busybox64 gunzip -c "%~1" ^| busybox64 head -c 11`) do set BLEND_HEAD=%%A set BLEND_HEAD=!BLEND_HEAD:_=-! set BLEND_HEAD=!BLEND_HEAD:V=v! if "!BLEND_HEAD!" == "BLENDER-v29" ( if not exist "%BLENDER_29%" exit "%BLENDER_29%" "%~1" ) else if "!BLEND_HEAD!" == "BLENDER-v28" ( if not exist "%BLENDER_28%" exit "%BLENDER_28%" "%~1" ) else if "!BLEND_HEAD!" == "BLENDER-v27" ( if not exist "%BLENDER_27%" exit "%BLENDER_27%" "%~1" ) ) endlocal
上で書いた「古いバージョンだとアンダースコアを使用しているが、2.7xのどこかの時点でなぜかハイフンに変わったようだ。」という記述は間違い。Blenderの仕様が変わったのではなくて筆者の環境が変わっていた、というオチだった。
これはこちらの記事で教わったのだが、'_' は32ビット、'-' は64ビットの環境で保存された場合に区別されるということだ。詳しくは上の記事を参照してほしい。他であまり見かけない、.blendファイルの構造について解説されていてとても参考になった。
また、vまたはVでendiannessを表している(小文字だとリトルエンディアン、大文字だとビッグエンディアン)こともこの記事で初めて知ったのだが、どちらも開けるようにした。ビッグエンディアンの環境で作成された.blendファイルを開く機会は現在ではまずありえないと思うが3……。