1
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

HyでBlenderのAdd-on Tutorialをやっていく

この記事は、Lisp Advent Carendar 2019 の 8日目の記事です。

この記事の要旨

Python 上で動作する Clojure ライクな Lisp の方言である Hy を使い、DCC ツールである Blender の Add-on を作成してみます。

対象読者

  • Python でやっていることを Lisp でやりたい人
  • Blender を Lisp でいじりたい人

環境構築

以下、Windows 10 の場合です。
他 OS の方は適宜読み替えてください(多少の説明はします)。

Python の環境構築

まず、Python 3 (64bit) をインストールします。
現時点 (2019/12) 最新の 3.8 系か、一つ前の 3.7 が良いでしょう。
公式サイトからインストーラを落としてきてインストールします。
32bit 版をインストールしないように注意しましょう。

Python 3 がインストール出来たら、環境を汚さないために Python の仮想環境である venv を作成し、そこに Hy をインストールします。今回は、ホームディレクトリ下の .virtualenvs ディレクトリ内に、venv_hy_blender という名前で作成します。
リリース版最新の Hy 0.17.0 にはまだ Type Annotation が実装されていないため、GitHub から 最新の master ブランチをインストールします。

Windows 10 の cmd では下記のように入力します。

$ cd %USERPROFILE%
$ mkdir .virtualenvs
$ cd .virtualenvs
$ py -3 -m venv venv_hy_blender
$ cd venv_hy_blender
$ Scripts\activate.bat
$ python -m pip install git+https://github.com/hylang/hy.git
$ deactivate.bat

py は Windows 専用のコマンドなので、他の OS の場合は py -3 の部分をその OS での Python 3 インタプリタ起動コマンドに置き換えます(大抵、python3 または python です)。
また、仮想環境を有効にするコマンド activate も OS や Shell ごとに異なるため、下記リンク「venv --- 仮想環境の作成」内の「仮想環境を有効化するためのコマンド」を参照ください。

Blender の環境構築

公式から現状最新の Blender 2.81 のインストーラを落としてインストールします。

Blender の Add-on 作成

以下が、Blender Add-on Tutorial の Bringing It All Together の Python コードを Hy に書き換えたものです。

Python を使っている人ならば、Python ほぼそのままで書けるということが分かると思います。
これを blender_sandbox ディレクトリに作成するものとします。

Hy の現行のドキュメントにない Type Annotation だけ説明しますと、(^型 変数名) です。詳細は「Implement PEP 3107 & 526 annotations」を参照ください。

cursor_array.hy
(import bpy)

(setv bl-info {
  :name "Cursor Array"
  :blender (, 2 81 0)
  :category "Object"
})


(defclass ObjectCursorArray [(. bpy types Operator)]
  "Object Cursor Array"
  (setv bl-idname "object.cursor_array")
  (setv bl-label "Cursor Array")
  (setv bl-options #{"REGISTER" "UNDO"})

  (^((. bpy props IntProperty) :name "Steps" :default 2 :min 1 :max 100) total)

  (defn execute [self context]
    (setv scene (. context scene))
    (setv cursor (. scene cursor location))
    (setv obj (. context active-object))

    (for [i (range (. self total))]
      (setv obj-new ((. obj copy)))
      ((. scene collection objects link) obj-new)

      (setv factor (/ i (. self total)))
      (setv (. obj-new location) (+ (* (. obj location) factor) (* cursor (- 1.0 factor)))))

    #{"FINISHED"}))


(defn menu_func [self context]
  ((. self layout operator) (. ObjectCursorArray bl-idname)))

; store keymaps here to access after registration
(setv addon-keymaps [])


(defn register []
  ((. bpy utils register-class) ObjectCursorArray)
  ((. bpy types VIEW3D-MT-object append) menu-func)

  ;; handle the keymap
  (setv wm (. bpy context window-manager))
  ;; Note that in background mode (no GUI available), keyconfigs are not available either,
  ;; so we have to check this to avoid nasty errors in background case.
  (setv kc (. wm keyconfigs addon))
  (when kc
    (setv km ((. wm keyconfigs addon keymaps new) :name "Object Mode" :space-type "EMPTY"))
    (setv kmi ((. km keymap-items new) (. ObjectCursorArray bl-idname) "T" "PRESS" :ctrl True :shift True))
    (setv (. kmi properties total) 4)
    ((. addon-keymaps append) (, km kmi))))

(defn unregister []
  ;; Note: when unregistering, it's usually good practice to do it in reverse order you registered.
  ;; Can avoid strange issues like keymap still referring to operators already unregistered...
  ;; handle the keymap
  (for [(, km kmi) addon-keymaps]
    ((. km keymap-items remove) kmi))
  ((. addon-keymaps clear))

  ((. bpy utils unregister-class) ObjectCursorArray)
  ((. bpy types VIEW3D-MT-object remove) menu-func))


(when (= --name-- "__main__")
    (register))

Blender 起動用バッチファイル作成

blender_sandbox ディレクトリに Blender2.81.bat という名前で起動用バッチファイルを作成します。
venv_hy_blendersite-packages と、作成した Add-on のディレクトリ(blender_sandbox)にパスを通し、Blender を起動するバッチファイルです。

site-packages は Python のサードパーティー製モジュールのインストール先ディレクトリで、Python 本体とそれぞれの仮想環境が持っています。
本来であれば activatedeactivate で仮想環境を切り替え、その site-packages を使うものですが、今回は Blender 2.81 内蔵の Python 3.7.4 に venv_hy_blender 内の Hy をインポートして使うために、若干邪法っぽいことをしています。

Blender2.81.bat
@ECHO OFF
SETLOCAL

SET THISDIR=%~dp0
SET PYTHONPATH=%THISDIR%;%USERPROFILE%\.virtualenvs\venv_hy_blender\Lib\site-packages;%PYTHONPATH%
SET BLENDER_EXE="C:\Program Files\Blender Foundation\Blender 2.81\blender.exe"

%BLENDER_EXE%

実行

このバッチファイルから Blender を起動し、上のメニューバーの Scripting を選択します。
Console から上記スクリプトをインポートするために、下記のように入力します。

>>> import hy
>>> import cursor_array
>>> cursor_array.register()

2019-12-08_13h08_05.png

これで、Layout > Object から Cursor Array を実行できるようになります。やってみましょう。

2019-12-08_12h58_51.png

2019-12-08_13h09_11.png

2019-12-08_13h09_18.png

2019-12-08_13h09_25.png

2019-12-08_13h09_35.png

2019-12-08_13h09_45.png

はい。

まとめ・補足

  • 仮想環境 venv 上で Python の環境構築すると元環境が汚されないので良いです。
  • Hy 0.17.0 ではまだ Type Annotation が使えませんが、今後使えるようになります。がっつり Hy を使いたい人は正式リリースを待ちましょう。
  • Python の邪法を駆使するなどして、いろいろなところで(例えばツール組み込みの Python 上で)Hy を動かすことができます。
  • 3DCG 界隈のツールは、ほとんどがスクリプト言語として Python を採用しているため、Hy も動きます。ただし現状は Blender などの一部のツール以外は Python 2 です。Hy は 0.17.0 まで Python 2 もサポートしていますが、今後はサポートしなくなるとのことです。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
1
Help us understand the problem. What are the problem?