Skip to content

Instantly share code, notes, and snippets.

@jabe0958
Last active February 14, 2018 15:31
Show Gist options
  • Save jabe0958/2d59ed97c6ce8afb3fdba24c64499bd7 to your computer and use it in GitHub Desktop.
Save jabe0958/2d59ed97c6ce8afb3fdba24c64499bd7 to your computer and use it in GitHub Desktop.
Blenderで対象のメッシュを螺旋状に複製して統合するPythonスクリプト
########################################################################
# ライブラリ読込
########################################################################
import numpy as np # まとめて計算するならNumPyがいるかと思ったがこの程度の計算量なら不要
import math
########################################################################
# パラメータ
########################################################################
src_obj_name = 'handitemr_mobacoincard' # 複製したいメッシュの名前
group_name = src_obj_name + '.armature' # 複製したいメッシュが所属しているグループ
loop = 10 # 螺旋の回転数
split = 32 # 1回転あたりの配置数(円周の分割数)
width_init = 1 # 中心からの平面距離初期値
width_incr = 0.01 # 中心からの平面距離の増分(広がりながら配置するため、円柱上なら0)
height_init = 0 # 高さ(Z座標)の初期値
height_loop = 0.8 # 1回転した時の高さ(Z座標)の増分(螺旋状に配置するため)
scale = 0.119 # 対象オブジェクトの拡大率(複製すると拡大率が初期化されるため、拡大縮小していなければ1)
remove_src_obj = True # 複製したい(オリジナル)メッシュの削除判定フラグ(残す場合は Flase)
########################################################################
# 初期化
########################################################################
# XYZ座標の記憶配列
X = []
Y = []
Z = []
# 変数初期化
r_step = (2 * math.pi) / split # オブジェクト間の平面上におけるラジアン
width = width_init # 中心からの距離
height = height_init # 高さ(Z座標)
height_incr = height_loop / split # オブジェクトを1個配置する際の高さの増分
########################################################################
# 配置先計算
########################################################################
cnt = 0 # 配置(複製)数、loop * split でも求められるがデバッグの際にあると便利なのでインクリメントで取得
# 回転数だけループ
for z in range(loop):
# 円周の分割数だけループ(これで1回転)
for r in range(split):
cnt += 1
X.append(width * np.cos(r * r_step)) # X座標を計算して設定、正直NumPy要らんかった
Y.append(width * np.sin(r * r_step)) # Y座標を計算して設定、正直NumPy要らんかった
Z.append(height) # Z座標を設定
width += width_incr # 中心からの平面距離を更新
height += height_incr # 高さを更新
########################################################################
# 複製配置
########################################################################
# 複製した数だけループ
first_obj_name = src_obj_name
for i in range(cnt):
# 一時的に複製メッシュの名称が必要になるため適当に設定
obj_name = 'tmp_' + str(i)
tmp = None
if i == 0 and remove_src_obj:
bpy.data.objects[src_obj_name].data.name = obj_name
bpy.data.objects[src_obj_name].name = obj_name
tmp = bpy.data.objects[obj_name]
first_obj_name = obj_name
else:
# 複製したいメッシュをベースに、複製メッシュの名称を指定して複製
tmp = bpy.data.objects.new(obj_name, bpy.data.objects[first_obj_name].data)
# シーンにリンク(この時点で3Dビューで見えるようになる)
bpy.context.scene.objects.link(tmp)
# 複製したメッシュの座標を指定(これで目的の座標に移動する)
tmp.location = (X[i], Y[i], Z[i])
# 複製したメッシュをアクティブに(これをしないと後続の拡大率変更でコケる、別の方法は無いのだろうか・・・)
bpy.context.scene.objects.active = bpy.data.objects[obj_name]
# 複製したメッシュの拡大率を変更
bpy.context.object.scale[0] = scale
bpy.context.object.scale[1] = scale
bpy.context.object.scale[2] = scale
# 複製したメッシュを中心方向に回転
bpy.context.object.rotation_euler = (0.0, -1.0, (2 * math.pi / split) * (i % split))
# 複製対象メッシュと同じグループに格納
bpy.data.objects[obj_name].parent = bpy.data.objects[group_name]
########################################################################
# 統合
########################################################################
# 一旦全ての選択を解除
bpy.ops.object.select_all(action='DESELECT')
# 複製対象(オリジナル)のメッシュを選択
if not remove_src_obj:
bpy.data.objects[first_obj_name].select = True
# 複製した全てのメッシュを選択
for i in range(cnt):
obj_name = 'tmp_' + str(i)
bpy.data.objects[obj_name].select = True
# 選択しているメッシュのいずれかを選択(このメッシュが統合後のメッシュの名称となる)
bpy.context.scene.objects.active = bpy.data.objects[first_obj_name]
# 選択した全てのメッシュを統合
bpy.ops.object.join()
# 統合したメッシュの名称を複製対象(オリジナル)のメッシュの名称にリネーム
bpy.data.objects[first_obj_name].data.name = src_obj_name
bpy.data.objects[first_obj_name].name = src_obj_name
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment