« スクリプトを書いてみた2 | Main | スクリプト小ネタ置き場 »

September 11, 2013

Cylinders on the Bones(Blender スクリプト)


んー、今度はArmatureを選択して実行するとそれに含まれるBoneの中心位置にCylinderを生成するスクリプトを書いてみました。(相変わらず英語は出鱈目です(^^;)


上の動画を見ていただくとわかると思いますが、そのCylinderを元に、Armatureへのスキニングが簡単なモデルを作ろうというものです。最初にArmatureで大体のプロポーションをとっておけば、素体モデルなんかも作るのが楽になるんじゃないかということで…

ただ、BoneのTailやHeadの座標取りや回転角度はなかなか一筋縄では行かないようで、当方、どうやったらスクリプトでBoneを選択してフォーカスを当てるのかわからずに悩むレベルですから、当然、そんなに高度なことはできません:-)

rigifyのスクリプトを見てedit_bonesに辿り着くまであっちを読んだりこっちを調べたりと3時間は七転八倒してました…まぢで(笑)

てなわけで、Boneの中心位置にただCylinderを置くだけなので、向きや大きさは全て手作業で修正しなければなりませんw


↓動作サンプルのblendファイル(blender 2.67bで作成)です

add_cylinders_on_bones04.blend

起動してそのままTEXT EditorのRun Scriptボタンを押すと、rigifyのメタリグのボーン上にCylinderが生成されます
2.68aでもメタリグへの生成は動きますが、うちの環境だと2.68aでrigfyがまともに動かないので、rigify入りの2.67b以下推奨です。


●スクリプト Cylinders on the Bones について

頭の4つの変数を変えることでCylinderの大きさを変えたり、辺の数、天地のフタの有無、cylinder生成後に一つの
オブジェクトにまとめるかどうかを指定できます。

sizeは1から6の値を設定。数が多いほどcylinderのサイズが大きくなります
cvは3以上(三角形以上)を指定します
cfは天地のフタの有無で、0が無し、1がNゴンの、2が三角ポリゴンで分割したフタがつきます
cjは0でCylinderオブジェクトをまとめない、1で一つのオブジェクトにまとめて、originをArmatureのorigin
と同じ座標にします

適当なArmatureを選択した状態で、以下の#,英語の部分の行のみをコピーしてBlenderのTextEditorでヘッダの
+ボタンを押し、新文書にペーストしてRunScriptボタンを押せば動くはずです。

############################
# add cylinders on the bones
############################

#!BPY
import bpy

size = 5    # cylinder size: 1(small)-> 6(big)
cv = 6    # cylinder's vertex number 3->
cf = 0    # cylinder opentype = 0, closetype = 1(Ngon) or 2(tri-Poly)
cj = 0    # cylinders join off = 0, on = 1

listEF = ['NOTHING','NGON','TRIFAN']
listSR = [0.25,0.5,1,1.5,2,3]
listSD = [0.5,1,2,3,4,5]

size -= 1
sclr = listSR[size]
scld = listSD[size]

scn = bpy.context.scene
oname = bpy.context.object.name

amt = bpy.data.objects[oname]
msh = bpy.ops.mesh
obj = bpy.ops.object
bcount = 0

bpy.context.area.type = 'VIEW_3D'

def objselect(objct):
    obj.mode_set(mode='OBJECT')
    scn.objects.active = objct
    objct.select = True


objselect(amt)

obj.mode_set(mode='EDIT')
bone = amt.data

for i in bone.edit_bones:
    bcount += 1
count = 0
rad = bone.edit_bones[0].tail_radius
print(bcount, rad)

for i in range(bcount):
    objselect(amt)
    obj.mode_set(mode='EDIT')
    bpy.ops.armature.select_all()
    bone.edit_bones[count].select = True
    bone.edit_bones[count].select_head = True
    bone.edit_bones[count].select_tail = True
    scn.objects[oname].data.edit_bones.active = bone.edit_bones[count]
    bpy.ops.view3d.snap_cursor_to_selected()
    msh.primitive_cylinder_add(vertices=cv,radius=rad*sclr,depth=rad*scld,end_fill_type=listEF[cf])
    count += 1

if (cj == 1):
    bpy.ops.object.select_grouped(type='TYPE')
    bpy.ops.object.join()
    newobj = bpy.context.object
    bpy.ops.object.select_all()
    objselect(amt)
    bpy.ops.view3d.snap_cursor_to_selected()
    objselect(newobj)
    obj.origin_set(type='ORIGIN_CURSOR')

bpy.context.area.type = 'TEXT_EDITOR'
#######################################

↑スクリプトここまで

|

« スクリプトを書いてみた2 | Main | スクリプト小ネタ置き場 »

Comments

The comments to this entry are closed.