[Blender3.3] 日本の地形モデルメッシュ追加アドオンの開発 (7): 独自アイコンの指定

前回までで一応動作するものになりましたが、改良の余地は沢山あります。

それらも一つ一つ調べながらやらないとなので、時間がかかりそうです。

さて、今回は追加メニューで表示するアイコンを独自のものに変えてみたいと思います。

最初にアイコンを作成します。


アイコンのサイズは縦横とも32ピクセルです。他のメニューに合わせて背景を黒、描画色を白にしました。TM_MESH_TERRAIN.png の名前でPNG形式で保存しておきます。
次に作るのは、読み込み用のモジュールです。icon.py としました。内容は下記の通りです。
# -*- coding: utf-8 -*-
#
# package: terrain_model
# file: icon.py

import os
import bpy
from trace import Trace


# We can store multiple preview collections here,
# however in this example we only store "main"
preview_collections = {}


def get_icon_id(name):
    
    pcoll = preview_collections["custom"]
    
    return pcoll[name].icon_id


def register():

    Trace.print("icon: register()")
    
    # Note that preview collections returned by bpy.utils.previews
    # are regular py objects - you can use them to store custom data.
    import bpy.utils.previews
    pcoll = bpy.utils.previews.new()

    # path to the folder where the icon is
    # the path is calculated relative to this py file inside the addon folder
    icons_dir = os.path.join(os.path.dirname(__file__), "icons")
    
    for root, dirs, files in os.walk(icons_dir):
        for file in files:
            (name, ext) = os.path.splitext(file)
            if ext == ".png":
                # load a preview thumbnail of a file and store in the previews collection
                Trace.print("icon: load as %s" % (name))
                pcoll.load(name, os.path.join(root, file), 'IMAGE')

    preview_collections["custom"] = pcoll


def unregister():

    for pcoll in preview_collections.values():
        bpy.utils.previews.remove(pcoll)

    preview_collections.clear()
内容は、モジュールファイルのあるフォルダの下のiconフォルダ下のPNGファイルを拾い出して読み込むというものです。Blenderにあったテンプレートをベースに修正。一応、汎用性のあるモジュールにしておきました。
それで、新しいモジュールファイルが増えたので、__init__.py もそのモジュールファイルを追加するように直します。
# -*- coding: utf-8 -*-
#
# package: terrain_model
# file: __init__.py

bl_info = {
    "name": "New Terrain Model (JP)",
    "author": "Shiki Kuraga",
    "version": (1, 0),
    "blender": (3, 3, 0),
    "location": "View3D > Add > Mesh > New Terrain Model (JP)",
    "description": "Adds a new Terrain Model (JP) Mesh Object",
    "warning": "",
    "support": "TESTING",
    "doc_url": "",
    "category": "Add Mesh",
}

__all__ = [ 'translation', 'icon', 'operator', 'model', 'hubeny_formula' ]

from . import translation
from . import icon
from . import operator

import bpy
from trace import Trace

## This allows you to right click on a button and link to documentation
#def add_object_manual_map():
#    url_manual_prefix = "https://docs.blender.org/manual/en/latest/"
#    url_manual_mapping = (
#        ("bpy.ops.mesh.add_object2", "scene_layout/object/types.html"),
#    )
#    return url_manual_prefix, url_manual_mapping


def register():
    Trace.print("register()")
    bpy.app.translations.register(__name__, translation.translation_dict)
    icon.register()
    operator.register()
#    bpy.utils.register_manual_map(add_object_manual_map)


def unregister():
    Trace.print("unregister()")
    operator.unregister()
    icon.unregister()
    bpy.app.translations.unregister(__name__)
#    bpy.utils.unregister_manual_map(add_object_manual_map)


if __name__ == "__main__":
    register()
やっていることは簡単で、__all__ に 'icon' を加えるのと、register(), unregister()にiconモジュールのregister(), unregister()を追加することだけです。
これらを踏まえて、メニュー生成処理をしているoperator.pyを手直しします。これはもう、変更部分だけ抽出して表示します。(これの前段で、"from . import icon" の宣言が必要)
def add_object_button(self, context):
    # insert separator
    self.layout.separator()
    self.layout.operator(
        OBJECT_OT_add_object.bl_idname,
        text = T("Terrain Model (JP)"),
        icon_value = icon.get_icon_id('TM_MESH_TERRAIN'))
#        icon = 'PLUGIN')
レイアウト設定で、icon = で指定していたアイコンを、icon_value = として独自アイコンのアイコンIDを設定しただけです。
結果、メニュー上のアイコンが新しいものになりました。


こうしてアイコンが独自のもので表示できると、気持ち良いですね。

前回(6)】日本の地形モデルメッシュ追加アドオンの開発 (7)


このブログの人気の投稿

パズドラ 転生龍刀士降臨周回編成 (ベア戦)

パズドラ HUNTER☓HUNTER キメラアント周回編成 (ペア戦)

[Blender3.3] mmd_toolsはどれが最新?