bl_info = {
    "name": "Sine Wave Generator (Space, Time & Phase Trajectory)",
    "author": "ChatGPT",
    "version": (1, 9, 0),
    "blender": (5, 0, 0),
    "location": "View3D > Sidebar (N Panel)",
    "description": "進行波と軌跡を描画します。波の位相(ズレ)も調整可能です。",
    "category": "3D View",
}

import bpy
import math

# ===================================
# 4. 共通定義
# ===================================
ADDON_TITLE = "Sine Wave Generator"
PREFIX_VAL = "SINE_WAVE"
ADDON_CATEGORY = "SineWave"
PREFIX = PREFIX_VAL.lower()

# =========================================================
# 6. 初期設定
# =========================================================
SINE_AMPLITUDE_DEFAULT = 2.0
SINE_FREQUENCY_DEFAULT = 1.0   
SINE_SPEED_DEFAULT = 2.0       
SINE_LENGTH_DEFAULT = 10.0     
SINE_TIME_DEFAULT = 0.0        
SINE_TIME_SCALE_DEFAULT = 1.0  
SINE_DELAY_DEFAULT = 0.0       
SINE_PHASE_OFFSET_DEFAULT = 0.0
SINE_RESOLUTION_DEFAULT = 128
SINE_THICKNESS_DEFAULT = 0.2
TRAJECTORY_TIME_MAX_DEFAULT = 10.0
TRAJECTORY_DRAW_DEFAULT = True
TRAJECTORY_TARGET_X_DEFAULT = 0.0    
TRAJECTORY_THICKNESS_DEFAULT = 0.15
PHASE_DRAW_DEFAULT = True
PHASE_TARGET_X_DEFAULT = 0.0
PHASE_TARGET_T_DEFAULT = 0.0
PHASE_THICKNESS_DEFAULT = 0.15
SINE_LOC_X_DEFAULT = 0.0
SINE_LOC_Y_DEFAULT = 0.0
SINE_LOC_Z_DEFAULT = 0.0
ALPHA_FRONT_DEFAULT = 1.0
ALPHA_BACK_DEFAULT = 0.5
COLOR_MAIN = (0.2, 0.6, 1.0, 1.0)
COLOR_TRAJECTORY = (1.0, 0.8, 0.1, 1.0)
COLOR_PHASE = (0.2, 1.0, 0.4, 1.0)

# ===================================
# プロパティ定義
# ===================================
class SineWaveProperties(bpy.types.PropertyGroup):
    # 物理パラメータ: z = A * sin( k * (x - v * (t - delay)) + offset )
    amplitude: bpy.props.FloatProperty(name="振幅 (A)", default=SINE_AMPLITUDE_DEFAULT)
    frequency: bpy.props.FloatProperty(name="周波数 (k)", default=SINE_FREQUENCY_DEFAULT)
    speed: bpy.props.FloatProperty(
        name="波の移動速度 (v)", 
        default=SINE_SPEED_DEFAULT, 
        description="正の値なら波は+X方向へ進み、時空軌跡も斜め奥へ進みます"
    )
    length: bpy.props.FloatProperty(name="描画する波の長さ", default=SINE_LENGTH_DEFAULT)
    
    time_t: bpy.props.FloatProperty(name="現在時間 (t)", default=SINE_TIME_DEFAULT)
    time_scale: bpy.props.FloatProperty(name="時間軸(Y)の送り速度", default=SINE_TIME_SCALE_DEFAULT)
    delay: bpy.props.FloatProperty(name="時間遅れ (delay)", default=SINE_DELAY_DEFAULT)
    phase_offset: bpy.props.FloatProperty(
        name="初期位相 (度)", 
        default=SINE_PHASE_OFFSET_DEFAULT, 
        description="-90にすると波の形が変わり、X軸/Y軸両方とも最初上に上がって見えます"
    )
    
    trajectory_time_max: bpy.props.FloatProperty(name="軌跡を描く時間長", default=TRAJECTORY_TIME_MAX_DEFAULT, min=0.1)
    
    draw_trajectory: bpy.props.BoolProperty(name="媒質点の軌跡を描画", default=TRAJECTORY_DRAW_DEFAULT)
    trajectory_x: bpy.props.FloatProperty(name="軌跡をとる X 座標", default=TRAJECTORY_TARGET_X_DEFAULT)
    trajectory_thickness: bpy.props.FloatProperty(name="軌跡の太さ", default=TRAJECTORY_THICKNESS_DEFAULT, min=0.0)
    color_trajectory: bpy.props.FloatVectorProperty(name="軌跡の色", subtype='COLOR', size=4, default=COLOR_TRAJECTORY, min=0.0, max=1.0)

    draw_phase: bpy.props.BoolProperty(name="位相点の時空軌跡を描画", default=PHASE_DRAW_DEFAULT)
    phase_x: bpy.props.FloatProperty(name="追跡開始 X", default=PHASE_TARGET_X_DEFAULT)
    phase_t: bpy.props.FloatProperty(name="追跡開始 t", default=PHASE_TARGET_T_DEFAULT)
    phase_thickness: bpy.props.FloatProperty(name="軌跡の太さ", default=PHASE_THICKNESS_DEFAULT, min=0.0)
    color_phase: bpy.props.FloatVectorProperty(name="軌跡の色", subtype='COLOR', size=4, default=COLOR_PHASE, min=0.0, max=1.0)

    resolution: bpy.props.IntProperty(name="解像度", default=SINE_RESOLUTION_DEFAULT, min=2)
    thickness: bpy.props.FloatProperty(name="波の太さ", default=SINE_THICKNESS_DEFAULT, min=0.0)
    color_main: bpy.props.FloatVectorProperty(name="波の色", subtype='COLOR', size=4, default=COLOR_MAIN, min=0.0, max=1.0)
    alpha_front: bpy.props.FloatProperty(name="透明度", default=ALPHA_FRONT_DEFAULT, min=0.0, max=1.0)

def create_curve_object(name, thickness, resolution):
    curve_data = bpy.data.curves.new(name=name, type='CURVE')
    curve_data.dimensions = '3D'
    curve_data.bevel_depth = thickness
    curve_data.bevel_resolution = 4
    spline = curve_data.splines.new(type='POLY')
    spline.points.add(resolution - 1)
    return curve_data, spline

def assign_material(obj, mat_name, color, alpha):
    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
        bsdf.inputs['Alpha'].default_value = alpha
    obj.data.materials.append(mat)

# ===================================
# オペレーター
# ===================================
class SINE_WAVE_OT_generate(bpy.types.Operator):
    bl_idname = f"{PREFIX}.generate"
    bl_label = "サイン波を生成"
    bl_description = "指定したパラメータで進行波と軌跡を生成します"

    def execute(self, context):
        props = context.scene.sine_wave_props
        rad_offset = math.radians(props.phase_offset)
        
        # ----------------------------------------------------
        # 1. 空間の波 (X方向に伸びる波)
        # ----------------------------------------------------
        curve_main, spline_main = create_curve_object("SineWaveCurve", props.thickness, props.resolution)
        for i in range(props.resolution):
            x = (i / (props.resolution - 1)) * props.length + SINE_LOC_X_DEFAULT
            y = (props.time_t * props.time_scale) + SINE_LOC_Y_DEFAULT
            
            # 物理的に正しい進行波: x - vt
            phase = props.frequency * (x - props.speed * (props.time_t - props.delay)) + rad_offset
            z = props.amplitude * math.sin(phase) + SINE_LOC_Z_DEFAULT
            
            spline_main.points[i].co = (x, y, z, 1.0)
            
        obj_main = bpy.data.objects.new(f"SineWave_t{props.time_t:.1f}", curve_main)
        context.collection.objects.link(obj_main)
        assign_material(obj_main, "SineWaveMaterial", props.color_main, props.alpha_front)

        # ----------------------------------------------------
        # 2. 媒質の波 (Y軸=時間軸 に伸びる特定のXの軌跡)
        # ----------------------------------------------------
        if props.draw_trajectory:
            curve_traj, spline_traj = create_curve_object("TrajectoryCurve", props.trajectory_thickness, props.resolution)
            for i in range(props.resolution):
                t_traj = (i / (props.resolution - 1)) * props.trajectory_time_max
                x_traj = props.trajectory_x + SINE_LOC_X_DEFAULT
                y_traj = (t_traj * props.time_scale) + SINE_LOC_Y_DEFAULT
                
                phase_traj = props.frequency * (props.trajectory_x - props.speed * (t_traj - props.delay)) + rad_offset
                z_traj = props.amplitude * math.sin(phase_traj) + SINE_LOC_Z_DEFAULT
                
                spline_traj.points[i].co = (x_traj, y_traj, z_traj, 1.0)
                
            obj_traj = bpy.data.objects.new(f"Trajectory_x{props.trajectory_x:.1f}", curve_traj)
            context.collection.objects.link(obj_traj)
            assign_material(obj_traj, "TrajectoryMaterial", props.color_trajectory, props.alpha_front)

        # ----------------------------------------------------
        # 3. 位相の時空軌跡 (+X, +T(Y) 方向へ斜めに進む一定位相の直線)
        # ----------------------------------------------------
        if props.draw_phase:
            curve_phase, spline_phase = create_curve_object("PhaseCurve", props.phase_thickness, props.resolution)
            
            # 位相は追跡開始時点のもので固定されるため、高さ(Z)は一定
            fixed_phase = props.frequency * (props.phase_x - props.speed * (props.phase_t - props.delay)) + rad_offset
            z_phase = props.amplitude * math.sin(fixed_phase) + SINE_LOC_Z_DEFAULT
            
            for i in range(props.resolution):
                t_p = (i / (props.resolution - 1)) * props.trajectory_time_max
                
                # 直感的な等速運動: X = X0 + v * t (波が右へ進むなら、位相点も右斜め奥へ進む)
                x_p = props.phase_x + props.speed * (t_p - props.phase_t) + SINE_LOC_X_DEFAULT
                y_p = (t_p * props.time_scale) + SINE_LOC_Y_DEFAULT
                
                spline_phase.points[i].co = (x_p, y_p, z_phase, 1.0)
                
            obj_phase = bpy.data.objects.new(f"Phase_x{props.phase_x:.1f}_t{props.phase_t:.1f}", curve_phase)
            context.collection.objects.link(obj_phase)
            assign_material(obj_phase, "PhaseMaterial", props.color_phase, props.alpha_front)

        return {'FINISHED'}

# ===================================
# UI パネル
# ===================================
class SINE_WAVE_PT_panel(bpy.types.Panel):
    bl_label = ADDON_TITLE
    bl_idname = f"{PREFIX}_PT_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = ADDON_CATEGORY

    def draw(self, context):
        layout = self.layout
        props = context.scene.sine_wave_props

        col = layout.column(align=True)
        col.prop(props, "amplitude")
        col.prop(props, "frequency")
        col.prop(props, "speed")     
        col.prop(props, "length")    
        
        col.separator()
        col.prop(props, "time_t")       
        col.prop(props, "time_scale")   
        col.prop(props, "delay")
        col.prop(props, "phase_offset") # 追加:初期位相
        
        col.separator()
        col.prop(props, "trajectory_time_max") 
        
        col.separator()
        col.prop(props, "draw_trajectory", text="媒質点の軌跡 (Y軸方向)", icon='OUTLINER_OB_CURVE')
        if props.draw_trajectory:
            box = col.box()
            box.prop(props, "trajectory_x")
            box.prop(props, "trajectory_thickness")
            box.prop(props, "color_trajectory")
            
        col.separator()
        col.prop(props, "draw_phase", text="位相の時空軌跡 (XY斜め方向)", icon='CURVE_PATH')
        if props.draw_phase:
            box = col.box()
            box.prop(props, "phase_x")
            box.prop(props, "phase_t")
            box.prop(props, "phase_thickness")
            box.prop(props, "color_phase")
            
        col.separator()
        col.prop(props, "resolution")
        col.prop(props, "thickness")
        col.prop(props, "color_main")
        col.prop(props, "alpha_front")
        
        layout.separator()
        row = layout.row()
        row.scale_y = 1.5
        row.operator(SINE_WAVE_OT_generate.bl_idname, text="波と軌跡を作成", icon='MOD_WAVE')

# ===================================
# 自動環境設定 (有効化時の処理)
# ===================================
def setup_viewport_ui():
    for window in bpy.context.window_manager.windows:
        for area in window.screen.areas:
            if area.type == 'VIEW_3D':
                for space in area.spaces:
                    if space.type == 'VIEW_3D':
                        space.shading.type = 'MATERIAL'
                        space.show_region_ui = True
    return None 

# ===================================
# 登録処理
# ===================================
classes = (
    SineWaveProperties,
    SINE_WAVE_OT_generate,
    SINE_WAVE_PT_panel,
)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.sine_wave_props = bpy.props.PointerProperty(type=SineWaveProperties)
    bpy.app.timers.register(setup_viewport_ui, first_interval=0.1)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)
    del bpy.types.Scene.sine_wave_props

if __name__ == "__main__":
    register()
bl_info = {
    "name": "Sine Wave Generator (X-Space, Y-Time, Z-Amplitude)",
    "author": "ChatGPT",
    "version": (1, 3, 0),
    "blender": (5, 0, 0),
    "location": "View3D > Sidebar (N Panel)",
    "description": "時間(t)を指定し、y=t のzx平面に波を描画します。時間経過で位相が進みます。",
    "category": "3D View",
}

import bpy
import math

# 作成日 2026年08月04日
# ===================================
# 4. 共通定義
# ===================================
ADDON_TITLE = "Sine Wave Generator"
PREFIX_VAL = "SINE_WAVE"
ADDON_CATEGORY = "SineWave"
PREFIX = PREFIX_VAL.lower()

# =========================================================
# 6. 初期設定
# =========================================================

# 数値
SINE_AMPLITUDE_DEFAULT = 2.0
SINE_FREQUENCY_DEFAULT = 1.0
SINE_LENGTH_DEFAULT = 10.0
SINE_TIME_DEFAULT = 0.0        # 時間 t (描画されるY座標)
SINE_DELAY_DEFAULT = 0.0       # 開始時間の遅れ
SINE_RESOLUTION_DEFAULT = 128
SINE_THICKNESS_DEFAULT = 0.2

# XYZ
SINE_LOC_X_DEFAULT = 0.0
SINE_LOC_Y_DEFAULT = 0.0
SINE_LOC_Z_DEFAULT = 0.0

# 透明度
ALPHA_FRONT_DEFAULT = 1.0
ALPHA_BACK_DEFAULT = 0.5

# テキスト
TEXT_SIZE_DEFAULT = 1.0
TEXT_OFFSET_X_DEFAULT = 0.0
TEXT_OFFSET_Y_DEFAULT = 0.0
TEXT_OFFSET_Z_DEFAULT = 0.0

# 色 (R, G, B, A)
COLOR_MAIN = (0.2, 0.6, 1.0, 1.0)
COLOR_SUB = (1.0, 0.4, 0.2, 1.0)

# ===================================
# プロパティ定義
# ===================================
class SineWaveProperties(bpy.types.PropertyGroup):
    amplitude: bpy.props.FloatProperty(name="振幅高さ (Z軸)", default=SINE_AMPLITUDE_DEFAULT)
    frequency: bpy.props.FloatProperty(name="周波数", default=SINE_FREQUENCY_DEFAULT)
    length: bpy.props.FloatProperty(name="波の長さ (X軸)", default=SINE_LENGTH_DEFAULT)
    
    time_t: bpy.props.FloatProperty(name="時間 t (Y座標)", default=SINE_TIME_DEFAULT, description="時間を進めるとY座標が移動し、波の位相も進みます")
    delay: bpy.props.FloatProperty(name="開始時間の遅れ", default=SINE_DELAY_DEFAULT, description="x=0基準での開始時間の遅れ")
    
    resolution: bpy.props.IntProperty(name="解像度", default=SINE_RESOLUTION_DEFAULT, min=2)
    thickness: bpy.props.FloatProperty(name="太さ", default=SINE_THICKNESS_DEFAULT, min=0.0)
    color_main: bpy.props.FloatVectorProperty(name="メインカラー", subtype='COLOR', size=4, default=COLOR_MAIN, min=0.0, max=1.0)
    alpha_front: bpy.props.FloatProperty(name="透明度", default=ALPHA_FRONT_DEFAULT, min=0.0, max=1.0)

# ===================================
# オペレーター (サイン波の生成)
# ===================================
class SINE_WAVE_OT_generate(bpy.types.Operator):
    bl_idname = f"{PREFIX}.generate"
    bl_label = "サイン波を生成"
    bl_description = "指定した時間(t)のzx平面(y=t)にサイン波を生成します"

    def execute(self, context):
        props = context.scene.sine_wave_props

        # カーブデータの作成 (太さを持たせる)
        curve_data = bpy.data.curves.new(name="SineWaveCurve", type='CURVE')
        curve_data.dimensions = '3D'
        curve_data.bevel_depth = props.thickness
        curve_data.bevel_resolution = 4
        
        # スプラインを追加
        spline = curve_data.splines.new(type='POLY')
        spline.points.add(props.resolution - 1)
        
        # 頂点座標の計算
        for i in range(props.resolution):
            # X軸 (空間的な広がり。中央を基準に配置)
            x = (i / (props.resolution - 1)) * props.length - (props.length / 2) + SINE_LOC_X_DEFAULT
            
            # Y軸 (時間 t に連動。y = t の平面)
            y = props.time_t + SINE_LOC_Y_DEFAULT
            
            # Z軸 (振幅高さ)
            # x=0を基準に、時間(time_t)と遅れ(delay)による位相の進行を計算
            z = props.amplitude * math.sin(props.frequency * x - (props.time_t - props.delay)) + SINE_LOC_Z_DEFAULT
            
            w = 1.0 # NURBS / POLY 用ウェイト
            spline.points[i].co = (x, y, z, w)
            
        # オブジェクトの作成とシーンへのリンク
        obj = bpy.data.objects.new(f"SineWave_t{props.time_t:.1f}", curve_data)
        context.collection.objects.link(obj)
        
        # マテリアルの作成と設定
        mat = bpy.data.materials.new(name="SineWaveMaterial")
        mat.use_nodes = True
        bsdf = mat.node_tree.nodes.get("Principled BSDF")
        if bsdf:
            bsdf.inputs['Base Color'].default_value = props.color_main
            bsdf.inputs['Alpha'].default_value = props.alpha_front
            mat.blend_method = 'BLEND'
            
        obj.data.materials.append(mat)

        return {'FINISHED'}

# ===================================
# UI パネル
# ===================================
class SINE_WAVE_PT_panel(bpy.types.Panel):
    bl_label = ADDON_TITLE
    bl_idname = f"{PREFIX}_PT_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = ADDON_CATEGORY

    def draw(self, context):
        layout = self.layout
        props = context.scene.sine_wave_props

        col = layout.column(align=True)
        col.prop(props, "amplitude")
        col.prop(props, "frequency")
        col.prop(props, "length")
        
        col.separator()
        col.prop(props, "time_t")  # 時間(t) / 描画されるY座標
        col.prop(props, "delay")   # 開始時間の遅れ
        
        col.separator()
        col.prop(props, "resolution")
        col.prop(props, "thickness")
        
        col.separator()
        col.prop(props, "color_main")
        col.prop(props, "alpha_front")
        
        layout.separator()
        
        row = layout.row()
        row.scale_y = 1.5
        row.operator(SINE_WAVE_OT_generate.bl_idname, text="サイン波を作成", icon='MOD_WAVE')

# ===================================
# 自動環境設定 (有効化時の処理)
# ===================================
def setup_viewport_ui():
    """アドオン有効化直後にNパネルを開き、マテリアルプレビューにする"""
    for window in bpy.context.window_manager.windows:
        for area in window.screen.areas:
            if area.type == 'VIEW_3D':
                for space in area.spaces:
                    if space.type == 'VIEW_3D':
                        # マテリアルプレビューに切り替え
                        space.shading.type = 'MATERIAL'
                        # Nパネルを開く
                        space.show_region_ui = True
    return None # タイマーを一度だけで終了させる

# ===================================
# 登録処理
# ===================================
classes = (
    SineWaveProperties,
    SINE_WAVE_OT_generate,
    SINE_WAVE_PT_panel,
)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.sine_wave_props = bpy.props.PointerProperty(type=SineWaveProperties)
    
    # アドオン有効化の0.1秒後にUIセットアップを実行する
    bpy.app.timers.register(setup_viewport_ui, first_interval=0.1)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)
    del bpy.types.Scene.sine_wave_props

if __name__ == "__main__":
    register()
bl_info = {
    "name": "Sine Wave Generator (Thick Curve)",
    "author": "ChatGPT",
    "version": (1, 0, 1),
    "blender": (5, 0, 0),
    "location": "View3D > Sidebar (N Panel)",
    "description": "y=0のzx平面に太さを持ったサイン波を描画します。",
    "category": "3D View",
}

import bpy
import math

# 作成日 2026年08月04日
# ===================================
# 4. 共通定義
# ===================================
ADDON_TITLE = "Sine Wave Generator"
PREFIX_VAL = "SINE_WAVE"
ADDON_CATEGORY = "SineWave"
PREFIX = PREFIX_VAL.lower()

# =========================================================
# 6. 初期設定
# =========================================================

# 数値
SINE_AMPLITUDE_DEFAULT = 2.0
SINE_FREQUENCY_DEFAULT = 1.0
SINE_LENGTH_DEFAULT = 10.0
SINE_RESOLUTION_DEFAULT = 128
SINE_THICKNESS_DEFAULT = 0.2

# XYZ
SINE_LOC_X_DEFAULT = 0.0
SINE_LOC_Y_DEFAULT = 0.0
SINE_LOC_Z_DEFAULT = 0.0

# 透明度
ALPHA_FRONT_DEFAULT = 1.0
ALPHA_BACK_DEFAULT = 0.5

# テキスト
TEXT_SIZE_DEFAULT = 1.0
TEXT_OFFSET_X_DEFAULT = 0.0
TEXT_OFFSET_Y_DEFAULT = 0.0
TEXT_OFFSET_Z_DEFAULT = 0.0

# 色 (R, G, B, A)
COLOR_MAIN = (0.2, 0.6, 1.0, 1.0)
COLOR_SUB = (1.0, 0.4, 0.2, 1.0)

# ===================================
# プロパティ定義
# ===================================
class SineWaveProperties(bpy.types.PropertyGroup):
    amplitude: bpy.props.FloatProperty(name="振幅", default=SINE_AMPLITUDE_DEFAULT)
    frequency: bpy.props.FloatProperty(name="周波数", default=SINE_FREQUENCY_DEFAULT)
    length: bpy.props.FloatProperty(name="長さ", default=SINE_LENGTH_DEFAULT)
    resolution: bpy.props.IntProperty(name="解像度", default=SINE_RESOLUTION_DEFAULT, min=2)
    thickness: bpy.props.FloatProperty(name="太さ", default=SINE_THICKNESS_DEFAULT, min=0.0)
    color_main: bpy.props.FloatVectorProperty(name="メインカラー", subtype='COLOR', size=4, default=COLOR_MAIN, min=0.0, max=1.0)
    alpha_front: bpy.props.FloatProperty(name="透明度", default=ALPHA_FRONT_DEFAULT, min=0.0, max=1.0)

# ===================================
# オペレーター (サイン波の生成)
# ===================================
class SINE_WAVE_OT_generate(bpy.types.Operator):
    bl_idname = f"{PREFIX}.generate"
    bl_label = "サイン波を生成"
    bl_description = "zx平面(y=0)に太さを持ったサイン波をカーブとして生成します"

    def execute(self, context):
        props = context.scene.sine_wave_props

        # カーブデータの作成 (太さを持たせるため bevel_depth を設定)
        curve_data = bpy.data.curves.new(name="SineWaveCurve", type='CURVE')
        curve_data.dimensions = '3D'
        curve_data.bevel_depth = props.thickness
        curve_data.bevel_resolution = 4
        
        # スプラインを追加
        spline = curve_data.splines.new(type='POLY')
        spline.points.add(props.resolution - 1)
        
        # 頂点座標の計算 (zx平面, y=0)
        for i in range(props.resolution):
            # 原点を中心として左右に配置
            x = (i / (props.resolution - 1)) * props.length - (props.length / 2) + SINE_LOC_X_DEFAULT
            y = SINE_LOC_Y_DEFAULT
            z = props.amplitude * math.sin(props.frequency * x) + SINE_LOC_Z_DEFAULT
            w = 1.0 # NURBS / POLY 用ウェイト
            spline.points[i].co = (x, y, z, w)
            
        # オブジェクトの作成とシーンへのリンク
        obj = bpy.data.objects.new("SineWave", curve_data)
        context.collection.objects.link(obj)
        
        # マテリアルの作成と設定
        mat = bpy.data.materials.new(name="SineWaveMaterial")
        mat.use_nodes = True
        bsdf = mat.node_tree.nodes.get("Principled BSDF")
        if bsdf:
            bsdf.inputs['Base Color'].default_value = props.color_main
            bsdf.inputs['Alpha'].default_value = props.alpha_front
            mat.blend_method = 'BLEND'
            
        obj.data.materials.append(mat)

        return {'FINISHED'}

# ===================================
# UI パネル
# ===================================
class SINE_WAVE_PT_panel(bpy.types.Panel):
    bl_label = ADDON_TITLE
    bl_idname = f"{PREFIX}_PT_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = ADDON_CATEGORY

    def draw(self, context):
        layout = self.layout
        props = context.scene.sine_wave_props

        col = layout.column(align=True)
        col.prop(props, "amplitude")
        col.prop(props, "frequency")
        col.prop(props, "length")
        col.prop(props, "resolution")
        col.prop(props, "thickness")
        
        col.separator()
        col.prop(props, "color_main")
        col.prop(props, "alpha_front")
        
        layout.separator()
        
        # ボタンを目立たせるために高さを変更し、確実なアイコンに変更
        row = layout.row()
        row.scale_y = 1.5
        row.operator(SINE_WAVE_OT_generate.bl_idname, text="サイン波を作成", icon='MOD_WAVE')

# ===================================
# 自動環境設定 (有効化時の処理)
# ===================================
def setup_viewport_ui():
    """アドオン有効化直後にNパネルを開き、マテリアルプレビューにする"""
    for window in bpy.context.window_manager.windows:
        for area in window.screen.areas:
            if area.type == 'VIEW_3D':
                for space in area.spaces:
                    if space.type == 'VIEW_3D':
                        # マテリアルプレビューに切り替え
                        space.shading.type = 'MATERIAL'
                        # Nパネルを開く
                        space.show_region_ui = True
    return None # タイマーを一度だけで終了させる

# ===================================
# 登録処理
# ===================================
classes = (
    SineWaveProperties,
    SINE_WAVE_OT_generate,
    SINE_WAVE_PT_panel,
)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.sine_wave_props = bpy.props.PointerProperty(type=SineWaveProperties)
    
    # アドオン有効化の0.1秒後にUIセットアップを実行する
    bpy.app.timers.register(setup_viewport_ui, first_interval=0.1)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)
    del bpy.types.Scene.sine_wave_props

if __name__ == "__main__":
    register()