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()