Sidebar > [ベクトル矢印ツール]", "description": "エラー修正版: テキストエディタ実行時でも自身のソースコードを取得して設定を保存できます。", "category": "Object", } # ============================================================================== # ★設定エリア (Global Configuration) # ============================================================================== PREFIX = "combined_vector_arrow" TAB_NAME = "[ベクトル矢印ツール]" # ▼ リンク設定リスト LINK_LIST = [ ("ドキュメント", "https://www.notion.so/20251110-2a6298fa488c8014ab50c3eaca269d90"), ] # ▼ パネル設定 ( "表示名", 1=開く / 0=閉じる ) # アルファベット順に整理 PANEL_CONFIGS = { "ARROW_PT_overlay_settings": ("A: Viewport オーバーレイ設定", 1), "ARROW_PT_p1": ("B: 単一ベクトル生成", 0"> Sidebar > [ベクトル矢印ツール]", "description": "エラー修正版: テキストエディタ実行時でも自身のソースコードを取得して設定を保存できます。", "category": "Object", } # ============================================================================== # ★設定エリア (Global Configuration) # ============================================================================== PREFIX = "combined_vector_arrow" TAB_NAME = "[ベクトル矢印ツール]" # ▼ リンク設定リスト LINK_LIST = [ ("ドキュメント", "https://www.notion.so/20251110-2a6298fa488c8014ab50c3eaca269d90"), ] # ▼ パネル設定 ( "表示名", 1=開く / 0=閉じる ) # アルファベット順に整理 PANEL_CONFIGS = { "ARROW_PT_overlay_settings": ("A: Viewport オーバーレイ設定", 1), "ARROW_PT_p1": ("B: 単一ベクトル生成", 0"> Sidebar > [ベクトル矢印ツール]", "description": "エラー修正版: テキストエディタ実行時でも自身のソースコードを取得して設定を保存できます。", "category": "Object", } # ============================================================================== # ★設定エリア (Global Configuration) # ============================================================================== PREFIX = "combined_vector_arrow" TAB_NAME = "[ベクトル矢印ツール]" # ▼ リンク設定リスト LINK_LIST = [ ("ドキュメント", "https://www.notion.so/20251110-2a6298fa488c8014ab50c3eaca269d90"), ] # ▼ パネル設定 ( "表示名", 1=開く / 0=閉じる ) # アルファベット順に整理 PANEL_CONFIGS = { "ARROW_PT_overlay_settings": ("A: Viewport オーバーレイ設定", 1), "ARROW_PT_p1": ("B: 単一ベクトル生成", 0">
# -*- coding: utf-8 -*-
# ---------------------------------------------------------------------
# アドオン基本情報
# ---------------------------------------------------------------------
bl_info = {
    "name": "ベクトル矢印 複合演算ツール (自動保存・ABC順)",
    "author": "Gemini & zionadchat",
    "version": (7, 8, 1),
    "blender": (4, 1, 0),
    "location": "View3D > Sidebar > [ベクトル矢印ツール]",
    "description": "エラー修正版: テキストエディタ実行時でも自身のソースコードを取得して設定を保存できます。",
    "category": "Object",
}

# ==============================================================================
#  ★設定エリア (Global Configuration)
# ==============================================================================
PREFIX = "combined_vector_arrow"
TAB_NAME = "[ベクトル矢印ツール]"

# ▼ リンク設定リスト
LINK_LIST = [
    ("ドキュメント", "<https://www.notion.so/20251110-2a6298fa488c8014ab50c3eaca269d90>"),
]

# ▼ パネル設定 ( "表示名", 1=開く / 0=閉じる )
# アルファベット順に整理
PANEL_CONFIGS = {
    "ARROW_PT_overlay_settings": ("A: Viewport オーバーレイ設定", 1),
    "ARROW_PT_p1": ("B: 単一ベクトル生成", 0),
    "ARROW_PT_p2": ("C: 終点連結 (V1+V2)", 0),
    "ARROW_PT_p3": ("D: ベクトル合算", 0),
    "ARROW_PT_3axis": ("E: 3軸 (XYZ) 生成", 1),
    "ARROW_PT_global_rot": ("F: グローバル回転", 0),
    "ARROW_PT_generate_script": ("G: 設定の保存・出力", 1),
    "ARROW_PT_links": ("H: リンク集", 0),
    "ARROW_PT_admin": ("I: 管理", 0),
}

# =================================================================================
# ★★★★★ 設定ブロック (保存されるデフォルト値) ★★★★★
# =================================================================================

SETTINGS_BLOCK = """
# --- Defaults for Panel1Props ---
"arrow_shape_preset": "太め",
"start_x": 5.000,
"start_y": 10.000,
"start_z": 10.000,
"end_x": 0.000,
"end_y": 0.000,
"end_z": 0.000,
"shaft_radius": 0.250,
"cone_radius": 0.600,
"cone_height": 2.000,
"cone_only": False,
"shaft_color": (0.470, 0.004, 0.280, 1.000),
"cone_color": (0.106, 0.000, 1.000, 1.000),
"object_name": "VectorArrow",
"parent_collection_name": "矢印ベクトル",

# --- Defaults for Panel2Props ---
"arrow_shape_preset": "太め",
"v1_start_x": 0.000,
"v1_start_y": 10.000,
"v1_start_z": 10.000,
"v1_end_x": 0.000,
"v1_end_y": 0.000,
"v1_end_z": 0.000,
"v2_end_x": 0.000,
"v2_end_y": -10.000,
"v2_end_z": 0.000,
"shaft_radius": 0.250,
"cone_radius": 0.600,
"cone_height": 2.000,
"cone_only": False,
"v1_color": (0.046, 1.000, 0.006, 1.000),
"v2_color": (1.000, 0.982, 0.015, 1.000),
"v3_color": (0.229, 0.017, 1.000, 1.000),

# --- Defaults for Panel3Props ---
"arrow_shape_preset": "円柱",
"v1_start_x": 0.000,
"v1_start_y": 10.000,
"v1_start_z": 0.000,
"v1_end_x": 0.000,
"v1_end_y": 10.000,
"v1_end_z": 10.000,
"v2_start_x": 5.000,
"v2_start_y": 10.000,
"v2_start_z": 0.000,
"v2_end_x": 5.000,
"v2_end_y": 10.000,
"v2_end_z": 10.000,
"shaft_radius": 1.000,
"cone_radius": 0.001,
"cone_height": 0.010,
"cone_only": False,
"v1_color": (1.000, 1.000, 0.000, 1.000),
"v2_color": (0.007, 0.005, 1.000, 1.000),
"v3_color": (1.000, 0.000, 1.000, 1.000),

# --- Defaults for Panel3AxisProps ---
"arrow_shape_preset": "標準",
"origin_x": 0.000,
"origin_y": 0.000,
"origin_z": 0.000,
"axis_length": 10.000,
"shaft_radius": 0.100,
"cone_radius": 0.300,
"cone_height": 0.800,
"cone_only": False,
"x_color": (1.000, 0.000, 0.000, 1.000),
"y_color": (0.000, 1.000, 0.000, 1.000),
"z_color": (0.000, 0.000, 1.000, 1.000),
"parent_collection_name": "矢印ベクトル",

# --- Defaults for GlobalRotationProperties ---
"rotation_x": 0.000,
"rotation_y": 0.000,
"rotation_z": 0.000,

# --- ARROW_GEOMETRY_PRESETS ---
ARROW_GEOMETRY_PRESETS = {
    "標準": { "shaft_radius": 0.1, "cone_radius": 0.4, "cone_height": 1.0 },
    "細め": { "shaft_radius": 0.05, "cone_radius": 0.2, "cone_height": 0.8 },
    "太め": { "shaft_radius": 0.25, "cone_radius": 0.6, "cone_height": 2.0 },
    "鋭角": { "shaft_radius": 0.08, "cone_radius": 0.2, "cone_height": 2.5 },
    "円柱": { "shaft_radius": 0.1, "cone_radius": 0.1, "cone_height": 0.01 },
}
"""
# =================================================================================
# ★★★★★ 設定ブロック (ここまで) ★★★★★
# =================================================================================

import bpy
import mathutils
import math
import webbrowser
import re
import ast
import inspect
import sys
import os
from mathutils import Matrix, Vector
from bpy.types import Operator, Panel, PropertyGroup
from bpy.props import StringProperty, FloatProperty, FloatVectorProperty, PointerProperty, EnumProperty, BoolProperty

# --- 設定解析 ---
def parse_settings_block(block_text):
    settings = {}
    current_section = None
    presets_str = ""
    in_presets = False
    for line in block_text.strip().split('\n'):
        line = line.strip()
        if not line: continue
        header_match = re.match(r'# --- Defaults for (\w+) ---', line)
        if header_match:
            current_section = header_match.group(1); settings[current_section] = {}; in_presets = False; continue
        if 'ARROW_GEOMETRY_PRESETS' in line: in_presets = True; current_section = None
        if in_presets: presets_str += line + '\n'; continue
        if current_section and ':' in line:
            try:
                key, value = line.split(':', 1); key = ast.literal_eval(key); value = value.strip().rstrip(',')
                settings[current_section][key] = ast.literal_eval(value)
            except: pass
    try:
        ns = {}; exec(presets_str, ns); settings['ARROW_GEOMETRY_PRESETS'] = ns.get('ARROW_GEOMETRY_PRESETS', {})
    except: settings['ARROW_GEOMETRY_PRESETS'] = {}
    return settings

PARSED_SETTINGS = parse_settings_block(SETTINGS_BLOCK)
ARROW_GEOMETRY_PRESETS = PARSED_SETTINGS.get('ARROW_GEOMETRY_PRESETS', {})
def _get_default(section, key, fallback): return PARSED_SETTINGS.get(section, {}).get(key, fallback)
def _generate_preset_items(): return [(name, name, f"プリセット「{name}」を適用") for name in ARROW_GEOMETRY_PRESETS.keys()]
ARROW_PRESET_ITEMS = _generate_preset_items()

ADDON_ID_PREFIX = PREFIX
ADDON_CATEGORY_NAME = TAB_NAME

# ---------------------------------------------------------------------
# 共通関数
# ---------------------------------------------------------------------
def get_or_create_collection(collection_name, parent_collection=None):
    if parent_collection is None: parent_collection = bpy.context.scene.collection
    if collection_name in parent_collection.children: return parent_collection.children[collection_name]
    new_collection = bpy.data.collections.new(collection_name)
    parent_collection.children.link(new_collection)
    return new_collection

def get_or_create_material(color, name_prefix="VecMat"):
    mat_name = f"{name_prefix}_{color[0]:.2f}_{color[1]:.2f}_{color[2]:.2f}_{color[3]:.2f}"
    if mat_name in bpy.data.materials: return bpy.data.materials[mat_name]
    mat = bpy.data.materials.new(name=mat_name); mat.use_nodes = True
    bsdf = mat.node_tree.nodes.get('Principled BSDF')
    if bsdf: bsdf.inputs['Base Color'].default_value = color
    return mat

def create_arrow_geometry(context, length, shaft_radius, cone_radius, cone_height, shaft_color, cone_color, cone_only=False):
    bpy.ops.object.select_all(action='DESELECT')
    if cone_only or length <= cone_height:
        final_cone_height = length
        final_cone_radius = cone_radius * (length / cone_height) if (cone_height > 1e-6 and not cone_only) else cone_radius
        bpy.ops.mesh.primitive_cone_add(radius1=final_cone_radius, depth=final_cone_height, vertices=32, location=(0,0,0))
        arrow_obj = context.active_object; arrow_obj.data.transform(Matrix.Translation((0,0,final_cone_height/2.0)))
        arrow_obj.data.materials.append(get_or_create_material(cone_color, "ConeColor"))
        return arrow_obj

    verts = []; faces = []; num_v = 32; shaft_length = length - cone_height
    verts.append(Vector((0,0,length)))
    for i in range(num_v): a=(i/num_v)*2*math.pi; verts.append(Vector((cone_radius*math.cos(a), cone_radius*math.sin(a), shaft_length)))
    for i in range(num_v): a=(i/num_v)*2*math.pi; verts.append(Vector((shaft_radius*math.cos(a), shaft_radius*math.sin(a), shaft_length)))
    for i in range(num_v): a=(i/num_v)*2*math.pi; verts.append(Vector((shaft_radius*math.cos(a), shaft_radius*math.sin(a), 0)))
    
    cone_f, shaft_f = [], []
    for i in range(num_v):
        i_n = (i+1)%num_v
        faces.append((0, 1+i_n, 1+i)); cone_f.append(len(faces)-1)
        faces.append((1+i, 1+i_n, 1+num_v+i_n, 1+num_v+i)); cone_f.append(len(faces)-1)
        faces.append((1+num_v+i, 1+num_v+i_n, 1+2*num_v+i_n, 1+2*num_v+i)); shaft_f.append(len(faces)-1)
    faces.append(tuple(reversed(range(1+2*num_v, 1+3*num_v)))); shaft_f.append(len(faces)-1)
    
    mesh = bpy.data.meshes.new("ArrowMesh"); mesh.from_pydata(verts, [], faces)
    obj = bpy.data.objects.new("ArrowObject", mesh)
    obj.data.materials.append(get_or_create_material(cone_color, "ConeColor")); obj.data.materials.append(get_or_create_material(shaft_color, "ShaftColor"))
    for idx in cone_f: obj.data.polygons[idx].material_index = 0
    for idx in shaft_f: obj.data.polygons[idx].material_index = 1
    mesh.update(); context.collection.objects.link(obj); context.view_layer.objects.active=obj; obj.select_set(True)
    return obj

def create_single_arrow_from_points(context, name, start, end, sr, cr, ch, sc, cc, co=False):
    direction = end - start; length = direction.length
    if length < 1e-6: return None
    obj = create_arrow_geometry(context, length, sr, cr, ch, sc, cc, co)
    if obj:
        obj.name = name; obj.location = start
        if direction.length > 0: obj.rotation_mode='QUATERNION'; obj.rotation_quaternion = direction.normalized().to_track_quat('Z','Y')
    return obj

def update_grid_scale(self, context):
    if context.space_data and context.space_data.type == 'VIEW_3D': context.space_data.overlay.grid_scale = self.scale

def update_panel_geometry_from_preset(self, context):
    if self.arrow_shape_preset in ARROW_GEOMETRY_PRESETS:
        for k,v in ARROW_GEOMETRY_PRESETS[self.arrow_shape_preset].items():
            if hasattr(self, k): setattr(self, k, v)

# ---------------------------------------------------------------------
# プロパティ
# ---------------------------------------------------------------------
class OverlaySettings(PropertyGroup):
    scale: FloatProperty(name="スケール", default=10.0, min=0.001, update=update_grid_scale, precision=2)

class Panel1Props(PropertyGroup):
    arrow_shape_preset: EnumProperty(name="形状プリセット", items=ARROW_PRESET_ITEMS, update=update_panel_geometry_from_preset, default=_get_default("Panel1Props", "arrow_shape_preset", "標準"))
    start_x: FloatProperty(name="X", default=_get_default("Panel1Props", "start_x", 0.0), precision=2)
    start_y: FloatProperty(name="Y", default=_get_default("Panel1Props", "start_y", 0.0), precision=2)
    start_z: FloatProperty(name="Z", default=_get_default("Panel1Props", "start_z", 0.0), precision=2)
    end_x: FloatProperty(name="X", default=_get_default("Panel1Props", "end_x", 5.0), precision=2)
    end_y: FloatProperty(name="Y", default=_get_default("Panel1Props", "end_y", 0.0), precision=2)
    end_z: FloatProperty(name="Z", default=_get_default("Panel1Props", "end_z", 18.52), precision=2)
    shaft_radius: FloatProperty(name="シャフト半径", default=_get_default("Panel1Props", "shaft_radius", 0.05), precision=2)
    cone_radius: FloatProperty(name="円錐半径", default=_get_default("Panel1Props", "cone_radius", 0.2), precision=2)
    cone_height: FloatProperty(name="円錐高さ", default=_get_default("Panel1Props", "cone_height", 0.8), precision=2)
    cone_only: BoolProperty(name="円錐のみ", default=_get_default("Panel1Props", "cone_only", False))
    shaft_color: FloatVectorProperty(name="シャフト色", subtype='COLOR', size=4, default=_get_default("Panel1Props", "shaft_color", (0.2,0.8,1,1)))
    cone_color: FloatVectorProperty(name="円錐色", subtype='COLOR', size=4, default=_get_default("Panel1Props", "cone_color", (0,0.4,0.8,1)))
    object_name: StringProperty(name="オブジェクト名", default=_get_default("Panel1Props", "object_name", "VectorArrow"))
    parent_collection_name: StringProperty(name="親コレクション名", default=_get_default("Panel1Props", "parent_collection_name", "矢印ベクトル"))

class Panel2Props(PropertyGroup):
    arrow_shape_preset: EnumProperty(name="形状プリセット", items=ARROW_PRESET_ITEMS, update=update_panel_geometry_from_preset, default=_get_default("Panel2Props", "arrow_shape_preset", "標準"))
    v1_start_x: FloatProperty(name="X", default=_get_default("Panel2Props", "v1_start_x", 0.0))
    v1_start_y: FloatProperty(name="Y", default=_get_default("Panel2Props", "v1_start_y", 0.0))
    v1_start_z: FloatProperty(name="Z", default=_get_default("Panel2Props", "v1_start_z", 0.0))
    v1_end_x: FloatProperty(name="X", default=_get_default("Panel2Props", "v1_end_x", 5.0))
    v1_end_y: FloatProperty(name="Y", default=_get_default("Panel2Props", "v1_end_y", 5.0))
    v1_end_z: FloatProperty(name="Z", default=_get_default("Panel2Props", "v1_end_z", 0.0))
    v2_end_x: FloatProperty(name="X", default=_get_default("Panel2Props", "v2_end_x", 10.0))
    v2_end_y: FloatProperty(name="Y", default=_get_default("Panel2Props", "v2_end_y", 0.0))
    v2_end_z: FloatProperty(name="Z", default=_get_default("Panel2Props", "v2_end_z", 0.0))
    shaft_radius: FloatProperty(name="シャフト半径", default=_get_default("Panel2Props", "shaft_radius", 0.1))
    cone_radius: FloatProperty(name="円錐半径", default=_get_default("Panel2Props", "cone_radius", 0.71))
    cone_height: FloatProperty(name="円錐高さ", default=_get_default("Panel2Props", "cone_height", 1.0))
    cone_only: BoolProperty(name="円錐のみ", default=_get_default("Panel2Props", "cone_only", False))
    v1_color: FloatVectorProperty(name="V1色", subtype='COLOR', size=4, default=_get_default("Panel2Props", "v1_color", (0.2,1,0.9,1)))
    v2_color: FloatVectorProperty(name="V2色", subtype='COLOR', size=4, default=_get_default("Panel2Props", "v2_color", (0,0,1,1)))
    v3_color: FloatVectorProperty(name="V3色", subtype='COLOR', size=4, default=_get_default("Panel2Props", "v3_color", (1,0.8,0,1)))

class Panel3Props(PropertyGroup):
    arrow_shape_preset: EnumProperty(name="形状プリセット", items=ARROW_PRESET_ITEMS, update=update_panel_geometry_from_preset, default=_get_default("Panel3Props", "arrow_shape_preset", "細め"))
    v1_start_x: FloatProperty(name="X", default=_get_default("Panel3Props", "v1_start_x", 0.0))
    v1_start_y: FloatProperty(name="Y", default=_get_default("Panel3Props", "v1_start_y", 10.0))
    v1_start_z: FloatProperty(name="Z", default=_get_default("Panel3Props", "v1_start_z", 0.0))
    v1_end_x: FloatProperty(name="X", default=_get_default("Panel3Props", "v1_end_x", 5.0))
    v1_end_y: FloatProperty(name="Y", default=_get_default("Panel3Props", "v1_end_y", 10.0))
    v1_end_z: FloatProperty(name="Z", default=_get_default("Panel3Props", "v1_end_z", 10.0))
    v2_start_x: FloatProperty(name="X", default=_get_default("Panel3Props", "v2_start_x", 5.0))
    v2_start_y: FloatProperty(name="Y", default=_get_default("Panel3Props", "v2_start_y", 10.0))
    v2_start_z: FloatProperty(name="Z", default=_get_default("Panel3Props", "v2_start_z", 0.0))
    v2_end_x: FloatProperty(name="X", default=_get_default("Panel3Props", "v2_end_x", 5.0))
    v2_end_y: FloatProperty(name="Y", default=_get_default("Panel3Props", "v2_end_y", 10.0))
    v2_end_z: FloatProperty(name="Z", default=_get_default("Panel3Props", "v2_end_z", 10.0))
    shaft_radius: FloatProperty(name="シャフト半径", default=_get_default("Panel3Props", "shaft_radius", 0.84))
    cone_radius: FloatProperty(name="円錐半径", default=_get_default("Panel3Props", "cone_radius", 0.2))
    cone_height: FloatProperty(name="円錐高さ", default=_get_default("Panel3Props", "cone_height", 0.8))
    cone_only: BoolProperty(name="円錐のみ", default=_get_default("Panel3Props", "cone_only", False))
    v1_color: FloatVectorProperty(name="V1色", subtype='COLOR', size=4, default=_get_default("Panel3Props", "v1_color", (1,1,0,1)))
    v2_color: FloatVectorProperty(name="V2色", subtype='COLOR', size=4, default=_get_default("Panel3Props", "v2_color", (0,1,1,1)))
    v3_color: FloatVectorProperty(name="V3色", subtype='COLOR', size=4, default=_get_default("Panel3Props", "v3_color", (1,0,1,1)))

class Panel3AxisProps(PropertyGroup):
    arrow_shape_preset: EnumProperty(name="形状プリセット", items=ARROW_PRESET_ITEMS, update=update_panel_geometry_from_preset, default=_get_default("Panel3AxisProps", "arrow_shape_preset", "標準"))
    origin_x: FloatProperty(name="原点X", default=_get_default("Panel3AxisProps", "origin_x", 0.0))
    origin_y: FloatProperty(name="原点Y", default=_get_default("Panel3AxisProps", "origin_y", 0.0))
    origin_z: FloatProperty(name="原点Z", default=_get_default("Panel3AxisProps", "origin_z", 0.0))
    axis_length: FloatProperty(name="各軸の長さ", default=_get_default("Panel3AxisProps", "axis_length", 5.0))
    shaft_radius: FloatProperty(name="シャフト半径", default=_get_default("Panel3AxisProps", "shaft_radius", 0.1))
    cone_radius: FloatProperty(name="円錐半径", default=_get_default("Panel3AxisProps", "cone_radius", 0.3))
    cone_height: FloatProperty(name="円錐高さ", default=_get_default("Panel3AxisProps", "cone_height", 0.8))
    cone_only: BoolProperty(name="円錐のみ", default=_get_default("Panel3AxisProps", "cone_only", False))
    x_color: FloatVectorProperty(name="X軸 色", subtype='COLOR', size=4, default=_get_default("Panel3AxisProps", "x_color", (1,0,0,1)))
    y_color: FloatVectorProperty(name="Y軸 色", subtype='COLOR', size=4, default=_get_default("Panel3AxisProps", "y_color", (0,1,0,1)))
    z_color: FloatVectorProperty(name="Z軸 色", subtype='COLOR', size=4, default=_get_default("Panel3AxisProps", "z_color", (0,0,1,1)))
    parent_collection_name: StringProperty(name="親コレクション名", default=_get_default("Panel3AxisProps", "parent_collection_name", "矢印ベクトル"))

class GlobalRotationProperties(PropertyGroup):
    rotation_x: FloatProperty(name="X", default=_get_default("GlobalRotationProperties", "rotation_x", 0.0), subtype='ANGLE')
    rotation_y: FloatProperty(name="Y", default=_get_default("GlobalRotationProperties", "rotation_y", 0.0), subtype='ANGLE')
    rotation_z: FloatProperty(name="Z", default=_get_default("GlobalRotationProperties", "rotation_z", 0.0), subtype='ANGLE')

# ---------------------------------------------------------------------
# オペレーター
# ---------------------------------------------------------------------
class ARROW_OT_SetOverlayScale(Operator):
    bl_idname = f"{ADDON_ID_PREFIX}.set_overlay_scale"; bl_label = "Overlayスケール"; bl_options = {'REGISTER', 'UNDO'}
    scale: FloatProperty()
    def execute(self, context): context.scene.overlay_settings.scale = self.scale; return {'FINISHED'}

class ARROW_OT_CreatePanel1(Operator):
    bl_idname = f"{ADDON_ID_PREFIX}.create_p1"; bl_label = "生成"; bl_options = {'REGISTER', 'UNDO'}
    def execute(self, context):
        p = context.scene.adv_vector_arrow_props_p1
        obj = create_single_arrow_from_points(context, p.object_name, Vector((p.start_x,p.start_y,p.start_z)), Vector((p.end_x,p.end_y,p.end_z)), p.shaft_radius, p.cone_radius, p.cone_height, p.shaft_color, p.cone_color, p.cone_only)
        if not obj: self.report({'WARNING'}, "生成失敗: 長さが足りません"); return {'CANCELLED'}
        col = get_or_create_collection(p.parent_collection_name); sub = get_or_create_collection(f"P1_{len(col.children):03d}_{p.object_name}", col)
        for c in obj.users_collection: c.objects.unlink(obj)
        sub.objects.link(obj); return {'FINISHED'}

class ARROW_OT_CreatePanel2(Operator):
    bl_idname = f"{ADDON_ID_PREFIX}.create_p2"; bl_label = "生成"; bl_options = {'REGISTER', 'UNDO'}
    def execute(self, context):
        p = context.scene.adv_vector_arrow_props_p2; p1 = context.scene.adv_vector_arrow_props_p1
        v1s=Vector((p.v1_start_x,p.v1_start_y,p.v1_start_z)); v1e=Vector((p.v1_end_x,p.v1_end_y,p.v1_end_z)); v2e=Vector((p.v2_end_x,p.v2_end_y,p.v2_end_z))
        sh={"sr":p.shaft_radius,"cr":p.cone_radius,"ch":p.cone_height,"co":p.cone_only}
        objs = [
            create_single_arrow_from_points(context,"V1",v1s,v1e,sh['sr'],sh['cr'],sh['ch'],p.v1_color,p.v1_color,sh['co']),
            create_single_arrow_from_points(context,"V2",v1e,v2e,sh['sr'],sh['cr'],sh['ch'],p.v2_color,p.v2_color,sh['co']),
            create_single_arrow_from_points(context,"V3_Sum",v1s,v2e,sh['sr'],sh['cr'],sh['ch'],p.v3_color,p.v3_color,sh['co'])
        ]
        col = get_or_create_collection(p1.parent_collection_name); sub = get_or_create_collection(f"P2_{len(col.children):03d}_Chain", col)
        for o in objs:
            if o:
                for c in o.users_collection: c.objects.unlink(o)
                sub.objects.link(o)
        return {'FINISHED'}

class ARROW_OT_CreatePanel3(Operator):
    bl_idname = f"{ADDON_ID_PREFIX}.create_p3"; bl_label = "生成"; bl_options = {'REGISTER', 'UNDO'}
    def execute(self, context):
        p = context.scene.adv_vector_arrow_props_p3; p1 = context.scene.adv_vector_arrow_props_p1
        v1s=Vector((p.v1_start_x,p.v1_start_y,p.v1_start_z)); v1e=Vector((p.v1_end_x,p.v1_end_y,p.v1_end_z))
        v2s=Vector((p.v2_start_x,p.v2_start_y,p.v2_start_z)); v2e=Vector((p.v2_end_x,p.v2_end_y,p.v2_end_z))
        v3e = (v1e-v1s) + (v2e-v2s)
        sh={"sr":p.shaft_radius,"cr":p.cone_radius,"ch":p.cone_height,"co":p.cone_only}
        objs = [
            create_single_arrow_from_points(context,"V1_Base",v1s,v1e,sh['sr'],sh['cr'],sh['ch'],p.v1_color,p.v1_color,sh['co']),
            create_single_arrow_from_points(context,"V2_Base",v2s,v2e,sh['sr'],sh['cr'],sh['ch'],p.v2_color,p.v2_color,sh['co']),
            create_single_arrow_from_points(context,"V3_Result",Vector((0,0,0)),v3e,sh['sr'],sh['cr'],sh['ch'],p.v3_color,p.v3_color,sh['co'])
        ]
        col = get_or_create_collection(p1.parent_collection_name); sub = get_or_create_collection(f"P3_{len(col.children):03d}_Sum", col)
        for o in objs:
            if o:
                for c in o.users_collection: c.objects.unlink(o)
                sub.objects.link(o)
        return {'FINISHED'}

class ARROW_OT_Create3Axis(Operator):
    bl_idname = f"{ADDON_ID_PREFIX}.create_3axis"; bl_label = "3軸(XYZ)生成"; bl_options = {'REGISTER', 'UNDO'}
    def execute(self, context):
        p = context.scene.adv_vector_arrow_props_3axis
        org = Vector((p.origin_x,p.origin_y,p.origin_z)); L = p.axis_length
        sh={"sr":p.shaft_radius,"cr":p.cone_radius,"ch":p.cone_height,"co":p.cone_only}
        objs = [
            create_single_arrow_from_points(context,"Axis_X",org,org+Vector((L,0,0)),sh['sr'],sh['cr'],sh['ch'],p.x_color,p.x_color,sh['co']),
            create_single_arrow_from_points(context,"Axis_Y",org,org+Vector((0,L,0)),sh['sr'],sh['cr'],sh['ch'],p.y_color,p.y_color,sh['co']),
            create_single_arrow_from_points(context,"Axis_Z",org,org+Vector((0,0,L)),sh['sr'],sh['cr'],sh['ch'],p.z_color,p.z_color,sh['co'])
        ]
        col = get_or_create_collection(p.parent_collection_name); sub = get_or_create_collection(f"3Axis_{len(col.children):03d}_XYZ", col)
        for o in objs:
            if o:
                for c in o.users_collection: c.objects.unlink(o)
                sub.objects.link(o)
        return {'FINISHED'}

class ARROW_OT_RotateGlobal(Operator):
    bl_idname = f"{ADDON_ID_PREFIX}.rotate_global"; bl_label = "適用"; bl_options = {'REGISTER', 'UNDO'}
    def execute(self, context):
        p = context.scene.adv_vector_arrow_props_global_rot
        if not context.selected_objects: return {'CANCELLED'}
        mat = Matrix.Translation(context.scene.cursor.location) @ Matrix.Rotation(p.rotation_z,4,'Z') @ Matrix.Rotation(-p.rotation_y,4,'Y') @ Matrix.Rotation(-p.rotation_x,4,'X') @ Matrix.Translation(-context.scene.cursor.location)
        for o in context.selected_objects: o.matrix_world = mat @ o.matrix_world
        return {'FINISHED'}

class ARROW_OT_ResetSingleProperty(Operator):
    bl_idname = f"{ADDON_ID_PREFIX}.reset_single_prop"; bl_label = ""; bl_options = {'REGISTER', 'UNDO'}
    prop_group_name: StringProperty(); prop_name: StringProperty()
    def execute(self, context):
        p = getattr(context.scene, self.prop_group_name); rna = p.bl_rna.properties.get(self.prop_name)
        if rna: setattr(p, self.prop_name, _get_default(p.bl_rna.name, self.prop_name, rna.default))
        return {'FINISHED'}

class ARROW_OT_ResetPanelProperties(Operator):
    bl_idname = f"{ADDON_ID_PREFIX}.reset_panel_props"; bl_label = ""; bl_options = {'REGISTER', 'UNDO'}
    panel_id: StringProperty()
    def execute(self, context):
        map = {"P1":"adv_vector_arrow_props_p1","P2":"adv_vector_arrow_props_p2","P3":"adv_vector_arrow_props_p3","3AXIS":"adv_vector_arrow_props_3axis","GLOBAL":"adv_vector_arrow_props_global_rot"}
        if not map.get(self.panel_id): return {'CANCELLED'}
        p = getattr(context.scene, map[self.panel_id]); sec = p.bl_rna.name
        for k in p.__annotations__.keys():
            if p.bl_rna.properties.get(k): setattr(p, k, _get_default(sec, k, p.bl_rna.properties[k].default))
        return {'FINISHED'}

# ★★★ 修正されたスクリプト生成オペレーター ★★★
class ARROW_OT_GenerateScript(Operator):
    bl_idname = f"{ADDON_ID_PREFIX}.generate_script"; bl_label = "設定済みスクリプトをエディタに出力"
    def execute(self, context):
        def fmt(v):
            if isinstance(v, str): return f'"{v}"'
            if isinstance(v, (mathutils.Vector, bpy.types.bpy_prop_array)): return f'({", ".join(f"{x:.3f}" for x in v)})'
            if isinstance(v, float): return f'{v:.3f}'
            return repr(v)
        
        scene = context.scene
        props_map = {
            "Panel1Props": scene.adv_vector_arrow_props_p1, "Panel2Props": scene.adv_vector_arrow_props_p2,
            "Panel3Props": scene.adv_vector_arrow_props_p3, "Panel3AxisProps": scene.adv_vector_arrow_props_3axis,
            "GlobalRotationProperties": scene.adv_vector_arrow_props_global_rot
        }
        
        new_conf = '\nSETTINGS_BLOCK = """\n'
        for cls, p in props_map.items():
            new_conf += f"# --- Defaults for {cls} ---\n"
            for k in p.__annotations__.keys(): new_conf += f'"{k}": {fmt(getattr(p, k))},\n'
            new_conf += "\n"
        new_conf += "# --- ARROW_GEOMETRY_PRESETS ---\nARROW_GEOMETRY_PRESETS = {\n"
        for n, d in ARROW_GEOMETRY_PRESETS.items(): new_conf += f'    "{n}": {{ "shaft_radius": {d["shaft_radius"]}, "cone_radius": {d["cone_radius"]}, "cone_height": {d["cone_height"]} }},\n'
        new_conf += "}\n"
        new_conf += '"""\n'

        # --- ソースコード取得ロジック (エラー修正版) ---
        source_code = ""
        # 1. テキストエディタのブロック名から取得を試みる
        # __file__ が "/Text.003" のようになっている場合、パスを除去して名前だけにする
        try:
            curr_file = __file__
            text_name = os.path.basename(curr_file) # \Text.003 -> Text.003
            # Windowsパスセパレータ等が残っている場合の保険
            if text_name.startswith('\\') or text_name.startswith('/'): text_name = text_name[1:]
            
            if text_name in bpy.data.texts:
                source_code = bpy.data.texts[text_name].as_string()
        except NameError: pass

        # 2. ファイルシステムから取得を試みる (インストール済みの場合)
        if not source_code:
            try:
                with open(__file__, 'r', encoding='utf-8') as f: source_code = f.read()
            except: pass
        
        # 3. inspect (最終手段)
        if not source_code:
            try: source_code = inspect.getsource(sys.modules[__name__])
            except: pass
        
        if not source_code:
            self.report({'ERROR'}, "ソースコードの取得に失敗しました。アドオンを保存してから実行してください。")
            return {'CANCELLED'}

        # 設定ブロックを置換
        pattern = r'SETTINGS_BLOCK\s*=\s*""".*?"""'
        match = re.search(pattern, source_code, re.DOTALL)
        if match:
            final_code = source_code[:match.start()] + new_conf.strip() + source_code[match.end():]
            new_text = bpy.data.texts.new(name="VectorArrow_Configured.py")
            new_text.write(final_code)
            # エディタ表示切り替え
            for area in context.screen.areas:
                if area.type == 'TEXT_EDITOR':
                    area.spaces[0].text = new_text
                    break
            self.report({'INFO'}, f"新しいスクリプトを作成しました: {new_text.name}")
            return {'FINISHED'}
        else:
            self.report({'ERROR'}, "設定ブロックが見つかりませんでした。")
            return {'CANCELLED'}

class ARROW_OT_OpenLink(Operator):
    bl_idname = f"{ADDON_ID_PREFIX}.open_link"; bl_label = "リンク"; url: StringProperty()
    def execute(self, context): webbrowser.open(self.url); return {'FINISHED'}

class ARROW_OT_RemoveAddon(Operator):
    bl_idname = f"{ADDON_ID_PREFIX}.remove_addon"; bl_label = "解除"
    def execute(self, context): unregister(); self.report({'INFO'}, "解除しました"); return {'FINISHED'}

class ARROW_OT_CopyShapeInfo(Operator):
    bl_idname = f"{ADDON_ID_PREFIX}.copy_shape_info"; bl_label = "情報コピー"; bl_options = {'REGISTER'}
    info_string: StringProperty()
    def execute(self, context): context.window_manager.clipboard = self.info_string; self.report({'INFO'}, "コピーしました"); return {'FINISHED'}

# ---------------------------------------------------------------------
# パネル
# ---------------------------------------------------------------------
def draw_prop_with_reset(layout, props, prop_name, grp, text=""):
    row = layout.row(align=True); row.prop(props, prop_name, text=text)
    op = row.operator(ARROW_OT_ResetSingleProperty.bl_idname, text="", icon='LOOP_BACK'); op.prop_group_name = grp; op.prop_name = prop_name

def draw_panel_header(layout, title, pid):
    row = layout.row(align=True); row.label(text=title)
    op = row.operator(ARROW_OT_ResetPanelProperties.bl_idname, text="", icon='FILE_REFRESH'); op.panel_id = pid

class ARROW_PT_OverlaySettingsPanel(Panel):
    bl_idname = "ARROW_PT_overlay_settings"; bl_space_type = 'VIEW_3D'; bl_region_type = 'UI'; bl_order = 1
    bl_label = PANEL_CONFIGS[bl_idname][0]; bl_category = TAB_NAME
    if not PANEL_CONFIGS[bl_idname][1]: bl_options = {'DEFAULT_CLOSED'}
    def draw(self, context):
        layout = self.layout; row = layout.row(align=True)
        row.prop(context.scene.overlay_settings, "scale")
        row.operator(ARROW_OT_SetOverlayScale.bl_idname, text="1").scale=1.0
        row.operator(ARROW_OT_SetOverlayScale.bl_idname, text="10").scale=10.0
        row.operator(ARROW_OT_SetOverlayScale.bl_idname, text="100").scale=100.0

class ARROW_PT_Panel1(Panel):
    bl_idname = "ARROW_PT_p1"; bl_space_type = 'VIEW_3D'; bl_region_type = 'UI'; bl_order = 2
    bl_label = PANEL_CONFIGS[bl_idname][0]; bl_category = TAB_NAME
    if not PANEL_CONFIGS[bl_idname][1]: bl_options = {'DEFAULT_CLOSED'}
    def draw(self, context):
        layout = self.layout; p = context.scene.adv_vector_arrow_props_p1; s = "adv_vector_arrow_props_p1"
        layout.operator(ARROW_OT_CreatePanel1.bl_idname, icon='ADD')
        b = layout.box(); draw_panel_header(b, "座標", "P1"); c = b.column(align=True)
        draw_prop_with_reset(c,p,"start_x",s,"始X"); draw_prop_with_reset(c,p,"start_y",s,"始Y"); draw_prop_with_reset(c,p,"start_z",s,"始Z")
        c.separator(); draw_prop_with_reset(c,p,"end_x",s,"終X"); draw_prop_with_reset(c,p,"end_y",s,"終Y"); draw_prop_with_reset(c,p,"end_z",s,"終Z")
        b = layout.box(); draw_panel_header(b, "形状", "P1"); c = b.column(align=True)
        L = (Vector((p.end_x,p.end_y,p.end_z))-Vector((p.start_x,p.start_y,p.start_z))).length
        c.label(text=f"長さ: {L:.2f}m"); c.prop(p,"cone_only"); c.prop(p,"arrow_shape_preset",text="")
        draw_prop_with_reset(c,p,"shaft_radius",s,"軸径"); draw_prop_with_reset(c,p,"cone_radius",s,"傘径"); draw_prop_with_reset(c,p,"cone_height",s,"傘高")
        b = layout.box(); draw_panel_header(b, "他", "P1"); c = b.column(align=True)
        c.prop(p,"shaft_color",text="軸色"); c.prop(p,"cone_color",text="傘色")
        draw_prop_with_reset(c,p,"object_name",s,"名"); draw_prop_with_reset(c,p,"parent_collection_name",s,"親コレ")

class ARROW_PT_Panel2(Panel):
    bl_idname = "ARROW_PT_p2"; bl_space_type = 'VIEW_3D'; bl_region_type = 'UI'; bl_order = 3
    bl_label = PANEL_CONFIGS[bl_idname][0]; bl_category = TAB_NAME
    if not PANEL_CONFIGS[bl_idname][1]: bl_options = {'DEFAULT_CLOSED'}
    def draw(self, context):
        layout = self.layout; p = context.scene.adv_vector_arrow_props_p2; s = "adv_vector_arrow_props_p2"
        layout.operator(ARROW_OT_CreatePanel2.bl_idname, icon='PLAY')
        b = layout.box(); draw_panel_header(b, "座標", "P2"); c = b.column(align=True)
        draw_prop_with_reset(c,p,"v1_start_x",s,"V1始X"); draw_prop_with_reset(c,p,"v1_start_y",s,"V1始Y"); draw_prop_with_reset(c,p,"v1_start_z",s,"V1始Z")
        c.separator(); draw_prop_with_reset(c,p,"v1_end_x",s,"V1終X"); draw_prop_with_reset(c,p,"v1_end_y",s,"V1終Y"); draw_prop_with_reset(c,p,"v1_end_z",s,"V1終Z")
        c.separator(); draw_prop_with_reset(c,p,"v2_end_x",s,"V2終X"); draw_prop_with_reset(c,p,"v2_end_y",s,"V2終Y"); draw_prop_with_reset(c,p,"v2_end_z",s,"V2終Z")
        b = layout.box(); draw_panel_header(b, "形状", "P2"); c = b.column(align=True)
        c.prop(p,"cone_only"); c.prop(p,"arrow_shape_preset",text="")
        draw_prop_with_reset(c,p,"shaft_radius",s,"軸径"); draw_prop_with_reset(c,p,"cone_radius",s,"傘径"); draw_prop_with_reset(c,p,"cone_height",s,"傘高")
        b = layout.box(); c = b.column(align=True); c.prop(p,"v1_color"); c.prop(p,"v2_color"); c.prop(p,"v3_color")

class ARROW_PT_Panel3(Panel):
    bl_idname = "ARROW_PT_p3"; bl_space_type = 'VIEW_3D'; bl_region_type = 'UI'; bl_order = 4
    bl_label = PANEL_CONFIGS[bl_idname][0]; bl_category = TAB_NAME
    if not PANEL_CONFIGS[bl_idname][1]: bl_options = {'DEFAULT_CLOSED'}
    def draw(self, context):
        layout = self.layout; p = context.scene.adv_vector_arrow_props_p3; s = "adv_vector_arrow_props_p3"
        layout.operator(ARROW_OT_CreatePanel3.bl_idname, icon='PLAY')
        b = layout.box(); draw_panel_header(b, "座標 (V1+V2=V3)", "P3"); c = b.column(align=True)
        draw_prop_with_reset(c,p,"v1_start_x",s,"V1始X"); draw_prop_with_reset(c,p,"v1_start_y",s,"V1始Y"); draw_prop_with_reset(c,p,"v1_start_z",s,"V1始Z")
        c.separator(); draw_prop_with_reset(c,p,"v1_end_x",s,"V1終X"); draw_prop_with_reset(c,p,"v1_end_y",s,"V1終Y"); draw_prop_with_reset(c,p,"v1_end_z",s,"V1終Z")
        c.separator(); draw_prop_with_reset(c,p,"v2_start_x",s,"V2始X"); draw_prop_with_reset(c,p,"v2_start_y",s,"V2始Y"); draw_prop_with_reset(c,p,"v2_start_z",s,"V2始Z")
        c.separator(); draw_prop_with_reset(c,p,"v2_end_x",s,"V2終X"); draw_prop_with_reset(c,p,"v2_end_y",s,"V2終Y"); draw_prop_with_reset(c,p,"v2_end_z",s,"V2終Z")
        b = layout.box(); draw_panel_header(b, "形状", "P3"); c = b.column(align=True)
        c.prop(p,"cone_only"); c.prop(p,"arrow_shape_preset",text="")
        draw_prop_with_reset(c,p,"shaft_radius",s,"軸径"); draw_prop_with_reset(c,p,"cone_radius",s,"傘径"); draw_prop_with_reset(c,p,"cone_height",s,"傘高")
        b = layout.box(); c = b.column(align=True); c.prop(p,"v1_color"); c.prop(p,"v2_color"); c.prop(p,"v3_color")

class ARROW_PT_3Axis(Panel):
    bl_idname = "ARROW_PT_3axis"; bl_space_type = 'VIEW_3D'; bl_region_type = 'UI'; bl_order = 5
    bl_label = PANEL_CONFIGS[bl_idname][0]; bl_category = TAB_NAME
    if not PANEL_CONFIGS[bl_idname][1]: bl_options = {'DEFAULT_CLOSED'}
    def draw(self, context):
        layout = self.layout; p = context.scene.adv_vector_arrow_props_3axis; s = "adv_vector_arrow_props_3axis"
        layout.operator(ARROW_OT_Create3Axis.bl_idname, icon='AXIS_SIDE')
        b = layout.box(); draw_panel_header(b, "設定", "3AXIS"); c = b.column(align=True)
        draw_prop_with_reset(c,p,"origin_x",s,"原点X"); draw_prop_with_reset(c,p,"origin_y",s,"原点Y"); draw_prop_with_reset(c,p,"origin_z",s,"原点Z")
        c.separator(); draw_prop_with_reset(c,p,"axis_length",s,"長さ")
        c.prop(p,"arrow_shape_preset",text="形状"); draw_prop_with_reset(c,p,"shaft_radius",s,"軸径"); draw_prop_with_reset(c,p,"cone_radius",s,"傘径"); draw_prop_with_reset(c,p,"cone_height",s,"傘高")
        c.separator(); c.prop(p,"x_color",text="X色"); c.prop(p,"y_color",text="Y色"); c.prop(p,"z_color",text="Z色")

class ARROW_PT_GlobalRotatePanel(Panel):
    bl_idname = "ARROW_PT_global_rot"; bl_space_type = 'VIEW_3D'; bl_region_type = 'UI'; bl_order = 6
    bl_label = PANEL_CONFIGS[bl_idname][0]; bl_category = TAB_NAME
    if not PANEL_CONFIGS[bl_idname][1]: bl_options = {'DEFAULT_CLOSED'}
    def draw(self, context):
        layout = self.layout; p = context.scene.adv_vector_arrow_props_global_rot; s = "adv_vector_arrow_props_global_rot"
        layout.operator(ARROW_OT_RotateGlobal.bl_idname, icon='CON_ROTLIKE')
        b = layout.box(); draw_panel_header(b, "回転", "GLOBAL"); c = b.column(align=True)
        draw_prop_with_reset(c,p,"rotation_x",s,"X"); draw_prop_with_reset(c,p,"rotation_y",s,"Y"); draw_prop_with_reset(c,p,"rotation_z",s,"Z")

class ARROW_PT_GenerateScriptPanel(Panel):
    bl_idname = "ARROW_PT_generate_script"; bl_space_type = 'VIEW_3D'; bl_region_type = 'UI'; bl_order = 7
    bl_label = PANEL_CONFIGS[bl_idname][0]; bl_category = TAB_NAME
    if not PANEL_CONFIGS[bl_idname][1]: bl_options = {'DEFAULT_CLOSED'}
    def draw(self, context):
        self.layout.operator(ARROW_OT_GenerateScript.bl_idname, icon='TEXT', text="設定を保存してスクリプト出力")

class ARROW_PT_LinksPanel(Panel):
    bl_idname = "ARROW_PT_links"; bl_space_type = 'VIEW_3D'; bl_region_type = 'UI'; bl_order = 8
    bl_label = PANEL_CONFIGS[bl_idname][0]; bl_category = TAB_NAME
    if not PANEL_CONFIGS[bl_idname][1]: bl_options = {'DEFAULT_CLOSED'}
    def draw(self, context):
        for n, u in LINK_LIST: self.layout.operator(ARROW_OT_OpenLink.bl_idname, text=n, icon='URL').url = u

class ARROW_PT_AdminPanel(Panel):
    bl_idname = "ARROW_PT_admin"; bl_space_type = 'VIEW_3D'; bl_region_type = 'UI'; bl_order = 9
    bl_label = PANEL_CONFIGS[bl_idname][0]; bl_category = TAB_NAME
    if not PANEL_CONFIGS[bl_idname][1]: bl_options = {'DEFAULT_CLOSED'}
    def draw(self, context): self.layout.operator(ARROW_OT_RemoveAddon.bl_idname, icon='CANCEL')

# ---------------------------------------------------------------------
# 登録
# ---------------------------------------------------------------------
classes = (
    OverlaySettings, Panel1Props, Panel2Props, Panel3Props, Panel3AxisProps, GlobalRotationProperties,
    ARROW_OT_SetOverlayScale, ARROW_OT_CreatePanel1, ARROW_OT_CreatePanel2, ARROW_OT_CreatePanel3, ARROW_OT_Create3Axis,
    ARROW_OT_RotateGlobal, ARROW_OT_OpenLink, ARROW_OT_RemoveAddon, ARROW_OT_ResetSingleProperty,
    ARROW_OT_ResetPanelProperties, ARROW_OT_GenerateScript, ARROW_OT_CopyShapeInfo,
    ARROW_PT_OverlaySettingsPanel, ARROW_PT_Panel1, ARROW_PT_Panel2, ARROW_PT_Panel3, ARROW_PT_3Axis,
    ARROW_PT_GlobalRotatePanel, ARROW_PT_GenerateScriptPanel, ARROW_PT_LinksPanel, ARROW_PT_AdminPanel,
)

def register():
    for c in classes: bpy.utils.register_class(c)
    s = bpy.types.Scene
    s.adv_vector_arrow_props_p1 = PointerProperty(type=Panel1Props)
    s.adv_vector_arrow_props_p2 = PointerProperty(type=Panel2Props)
    s.adv_vector_arrow_props_p3 = PointerProperty(type=Panel3Props)
    s.adv_vector_arrow_props_3axis = PointerProperty(type=Panel3AxisProps)
    s.adv_vector_arrow_props_global_rot = PointerProperty(type=GlobalRotationProperties)
    s.overlay_settings = PointerProperty(type=OverlaySettings)

def unregister():
    for p in ['adv_vector_arrow_props_p1','adv_vector_arrow_props_p2','adv_vector_arrow_props_p3','adv_vector_arrow_props_3axis','adv_vector_arrow_props_global_rot','overlay_settings']:
        if hasattr(bpy.types.Scene, p): delattr(bpy.types.Scene, p)
    for c in reversed(classes): bpy.utils.unregister_class(c)

if __name__ == "__main__":
    try: unregister()
    except: pass
    register()