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

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

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

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

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


アイコンのサイズは縦横とも32ピクセルです。他のメニューに合わせて背景を黒、描画色を白にしました。TM_MESH_TERRAIN.png の名前でPNG形式で保存しておきます。
次に作るのは、読み込み用のモジュールです。icon.py としました。内容は下記の通りです。
  1. # -*- coding: utf-8 -*-
  2. #
  3. # package: terrain_model
  4. # file: icon.py
  5.  
  6. import os
  7. import bpy
  8. from trace import Trace
  9.  
  10.  
  11. # We can store multiple preview collections here,
  12. # however in this example we only store "main"
  13. preview_collections = {}
  14.  
  15.  
  16. def get_icon_id(name):
  17. pcoll = preview_collections["custom"]
  18. return pcoll[name].icon_id
  19.  
  20.  
  21. def register():
  22.  
  23. Trace.print("icon: register()")
  24. # Note that preview collections returned by bpy.utils.previews
  25. # are regular py objects - you can use them to store custom data.
  26. import bpy.utils.previews
  27. pcoll = bpy.utils.previews.new()
  28.  
  29. # path to the folder where the icon is
  30. # the path is calculated relative to this py file inside the addon folder
  31. icons_dir = os.path.join(os.path.dirname(__file__), "icons")
  32. for root, dirs, files in os.walk(icons_dir):
  33. for file in files:
  34. (name, ext) = os.path.splitext(file)
  35. if ext == ".png":
  36. # load a preview thumbnail of a file and store in the previews collection
  37. Trace.print("icon: load as %s" % (name))
  38. pcoll.load(name, os.path.join(root, file), 'IMAGE')
  39.  
  40. preview_collections["custom"] = pcoll
  41.  
  42.  
  43. def unregister():
  44.  
  45. for pcoll in preview_collections.values():
  46. bpy.utils.previews.remove(pcoll)
  47.  
  48. preview_collections.clear()
内容は、モジュールファイルのあるフォルダの下のiconフォルダ下のPNGファイルを拾い出して読み込むというものです。Blenderにあったテンプレートをベースに修正。一応、汎用性のあるモジュールにしておきました。
それで、新しいモジュールファイルが増えたので、__init__.py もそのモジュールファイルを追加するように直します。
  1. # -*- coding: utf-8 -*-
  2. #
  3. # package: terrain_model
  4. # file: __init__.py
  5.  
  6. bl_info = {
  7. "name": "New Terrain Model (JP)",
  8. "author": "Shiki Kuraga",
  9. "version": (1, 0),
  10. "blender": (3, 3, 0),
  11. "location": "View3D > Add > Mesh > New Terrain Model (JP)",
  12. "description": "Adds a new Terrain Model (JP) Mesh Object",
  13. "warning": "",
  14. "support": "TESTING",
  15. "doc_url": "",
  16. "category": "Add Mesh",
  17. }
  18.  
  19. __all__ = [ 'translation', 'icon', 'operator', 'model', 'hubeny_formula' ]
  20.  
  21. from . import translation
  22. from . import icon
  23. from . import operator
  24.  
  25. import bpy
  26. from trace import Trace
  27.  
  28. ## This allows you to right click on a button and link to documentation
  29. #def add_object_manual_map():
  30. # url_manual_prefix = "https://docs.blender.org/manual/en/latest/"
  31. # url_manual_mapping = (
  32. # ("bpy.ops.mesh.add_object2", "scene_layout/object/types.html"),
  33. # )
  34. # return url_manual_prefix, url_manual_mapping
  35.  
  36.  
  37. def register():
  38. Trace.print("register()")
  39. bpy.app.translations.register(__name__, translation.translation_dict)
  40. icon.register()
  41. operator.register()
  42. # bpy.utils.register_manual_map(add_object_manual_map)
  43.  
  44.  
  45. def unregister():
  46. Trace.print("unregister()")
  47. operator.unregister()
  48. icon.unregister()
  49. bpy.app.translations.unregister(__name__)
  50. # bpy.utils.unregister_manual_map(add_object_manual_map)
  51.  
  52.  
  53. if __name__ == "__main__":
  54. 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)


このブログの人気の投稿

パズドラ 12月のクエスト(Lv12) ネフティスさん、出番です

日本酒 烏輪 緑のたいよう 純米酒 無濾過生原酒

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