初期設定 blender 5

追加する
# =========================================================
# 1. bl_info
# =========================================================
bl_info = {
    "name": "Remove addon",
    "author": "Your Name",
    "version": (1, 4, 0),
    "blender": (5, 0, 0),
    "location": "View3D > Sidebar > HemiStar",
    "description": "dome, 2 stars (angle UV), and 2 observers with Size controls.",
    "category": "3D View",
}

# =========================================================
# 2. コード作成日時
# =========================================================
# Code Created : 2024_0525_1600

# =========================================================
# 3. import
# =========================================================
import bpy
import bmesh
import math
import webbrowser

# =========================================================
# 4. 共通定義
# =========================================================
ADDON_TITLE = "111 Star Sim"
PREFIX_VAL = "STAR3333"
PREFIX = PREFIX_VAL.lower()
ADDON_CATEGORY = "2222 Star"

# ===================================================================
# 5. 【リンク定義】 
# ===================================================================
# 1番はユーザー指定のカスタムリンク用に空き、2〜4番に下記定義を設定
LINK_NAME_2 = "コンテナ builder"
LINK_URL_2 = "<https://note.com/zionad2017/n/ndb6dbdbc844a>"
LINK_NAME_3 = "posfie"
LINK_URL_3 = "<https://posfie.com/@timekagura/t/zionad2022?sort=0>"
LINK_NAME_4 = "zionadchat"
LINK_URL_4 = "<https://x.com/zionadchat>"

# ===================================================================
# 6. オペレーター (リンク起動 & アドオン無効化)
# ===================================================================
class STAR_OT_OpenUrl(bpy.types.Operator):
    bl_idname = f"{PREFIX}.open_url"
    bl_label = "リンクを開く"
    
    url: bpy.props.StringProperty()
    
    def execute(self, context):
        webbrowser.open(self.url)
        return {'FINISHED'}

class STAR_OT_RemoveAddon(bpy.types.Operator):
    bl_idname = f"{PREFIX}.remove_addon"
    bl_label = "Unregister Addon"
    bl_description = "このアドオンを無効化し、UIから消去します"
    
    def execute(self, context):
        # 即座にunregisterせず、タイマーを用いて安全に解除処理を遅延実行する
        bpy.app.timers.register(unregister, first_interval=0.01)
        return {'FINISHED'}

# ===================================================================
# 7. UIパネル (リンク & アドオン削除)
# ===================================================================
class STAR_PT_LinksPanel(bpy.types.Panel):
    bl_label = "リンク"
    bl_idname = f"{PREFIX_VAL}_PT_links_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = ADDON_CATEGORY
    bl_order = 1

    def draw(self, context):
        layout = self.layout
        box = layout.box()
        
        if LINK_NAME_2:
            op2 = box.operator(STAR_OT_OpenUrl.bl_idname, text=LINK_NAME_2, icon='URL')
            op2.url = LINK_URL_2
        
        if LINK_NAME_3:
            op3 = box.operator(STAR_OT_OpenUrl.bl_idname, text=LINK_NAME_3, icon='URL')
            op3.url = LINK_URL_3

        if LINK_NAME_4:
            op4 = box.operator(STAR_OT_OpenUrl.bl_idname, text=LINK_NAME_4, icon='URL')
            op4.url = LINK_URL_4

class STAR_PT_RemovePanel(bpy.types.Panel):
    bl_label = "アドオン削除"
    bl_idname = f"{PREFIX_VAL}_PT_remove_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = ADDON_CATEGORY
    bl_options = {'DEFAULT_CLOSED'}
    bl_order = 2

    def draw(self, context):
        layout = self.layout
        box = layout.box()
        box.label(text="このアドオンを消去します", icon='ERROR')
        box.operator(STAR_OT_RemoveAddon.bl_idname, icon='CANCEL')

# ===================================================================
# 8. 登録・解除
# ===================================================================
classes = (
    STAR_OT_OpenUrl,
    STAR_OT_RemoveAddon,
    STAR_PT_LinksPanel,
    STAR_PT_RemovePanel,
)

'''
## 10. register()

最後に

* Class登録
* Property登録
* Menu登録

を行う。

---

## 11. unregister()

register() の逆順で解除する。

* Menu解除
* Property解除
* Class解除 

これを読んだ生成AIが どうアドオン削除パネル作ればよいか わかるように
'''

def register():
    for cls in classes:
        bpy.utils.register_class(cls)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)

if __name__ == "__main__":
    register()