Blender 自動化スクリプトで定形オブジェクト作成で楽をする、円柱とボーンを追加するWiggle2ポーズモード

 BlenderはPythonスクリプトを実行して、命令やオブジェクトを作成できる。これで定形オブジェクト作成で楽をする。自動化すると楽になる。

次のスクリプトは、1個の円柱を作成して、指定された数の親子ボーンを追加するまでのスクリプト。実行環境はWindows10:Blender4.2

内部メモ、C:\Users\mased\Documents\Blender\blender\model\テスト、研究モデル\しっぽ揺れアニメ\Wiggle実験尻尾揺れ、2024年10月9日、ファイル名make_obj_automticWeight_006.py ダウンロードファイルはなし(ウィルス感染とか内容の更新とかできないので、、Githubという方法もあるが仕組みが未だに理解できないので使えない老衰脳)

Wiggl2のStiffは数値が高いほど固く、数値が低いほど柔い。なので、Stiff:200が柔らかく、800とかだと固い。(訂正) 数値が高いほど揺れやすい。低いほど固い動きになる。だからTailの尻尾の先にStiff800以上にするとすごく揺れまくる。これは実際にアニメーションして動きをチェックして確認が必要


ブログ内関連リンク、マテリアル設定スクリプト記事



gDepthは円柱の高さ、gCountBonesは作成するボーンの数。無制限に作成するわけにいかないが、円柱の高さに見合うボーンの数を入力する。


実行文はinfo情報から取得しているので、無駄なパラメータも多いかもしれん。エラー処理は殆ど無いので、極端な数値は入れないようにしたほうがよい。

For文のrange(N)は、「0から始まってN-1」まで。個数はN個。なんとなく「0からN」までか「1からN」までのように思うが実際は違うので勘違いしないように。

  1. import os
  2. import bpy
  3. import math
  4. import copy
  5. import time
  6. #2024/10/9
  7.  
  8. #make obj 円柱作成 Blender text ここでは日本語の入力はできないので、他で入力してコピペして
  9.  
  10.  
  11. if __name__ == "__main__":
  12. #main GO
  13. #var
  14. gDepth=6# cylinder hight 円柱高さ6mに対して、ボーンの最大数は11か12個くらい
  15. gCountBones=6# bone count over 2 number.limit count is [11 or 12]. << by gDepth:6
  16. # 3Dカーソルの位置を元に戻す
  17. bpy.context.scene.cursor.location=(0.0,0.0,0.0)
  18. #円柱Vertices16,半径0.5m、Depth6m 座標:0,0,3m(Depth6m/2)
  19. # location=(0, 0, 3)#z is 3m , Depth is 6m, its half size.
  20. bpy.ops.mesh.primitive_cylinder_add(vertices=16,radius=0.5, depth=gDepth, enter_editmode=False, align='WORLD', location=(0, 0, gDepth/2), scale=(1, 1, 1))
  21. #CTR+R bunkatsu 16 cuts
  22. bpy.ops.object.editmode_toggle()
  23. bpy.ops.mesh.loopcut_slide(MESH_OT_loopcut={"number_cuts":16, "smoothness":0, "falloff":'INVERSE_SQUARE', "object_index":0, "edge_index":15, "mesh_select_mode_init":(True, False, False)}, TRANSFORM_OT_edge_slide={"value":0, "single_side":False, "use_even":False, "flipped":False, "use_clamp":True, "mirror":True, "snap":False, "snap_elements":{'INCREMENT'}, "use_snap_project":False, "snap_target":'CLOSEST', "use_snap_self":True, "use_snap_edit":True, "use_snap_nonedit":True, "use_snap_selectable":False, "snap_point":(0, 0, 0), "correct_uv":True, "release_confirm":False, "use_accurate":False})
  24. bpy.ops.object.editmode_toggle()#from edit to OBJ mode
  25.  
  26. # next is bone add .
  27. #bpy.context.space_data.shading.type = 'WIREFRAME'
  28. #add bone 1
  29. bpy.ops.object.armature_add(enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(1, 1, gDepth/gCountBones)) #6/4=1.5
  30. # Edit mode
  31. bpy.ops.object.editmode_toggle()
  32. #add bone2 to (gCountBones-1)
  33. #E key EXTRUDE add child bone
  34. if gCountBones < 2:#最低でも2個は作成する
  35. gCountBones=2
  36. #range(num) is 0 to num-1. exp: num=9 then 012345678 , its 9 counts. not exist [number9] .
  37. for i in range(gCountBones):# range() is from 0 to (gcountBones-1), total count is [gCountBOnes].
  38. if i >= gCountBones-1:
  39. break
  40. else:
  41. bpy.ops.armature.extrude_move(ARMATURE_OT_extrude={"forked":False},\
  42. TRANSFORM_OT_translate={"value":(0, 0, gDepth/gCountBones),\
  43. "orient_type":'GLOBAL',\
  44. "orient_matrix":((1, 0, 0), (0, 1, 0), (0, 0, 1)),\
  45. "orient_matrix_type":'GLOBAL', "constraint_axis":(False, False, True),\
  46. "mirror":False, "use_proportional_edit":False,\
  47. "proportional_edit_falloff":'SMOOTH',\
  48. "proportional_size":1,\
  49. "use_proportional_connected":False,\
  50. "use_proportional_projected":False,\
  51. "snap":False, "snap_elements":{'INCREMENT'},\
  52. "use_snap_project":False, "snap_target":'CLOSEST',\
  53. "use_snap_self":True, "use_snap_edit":True,\
  54. "use_snap_nonedit":True, "use_snap_selectable":False,\
  55. "snap_point":(0, 0, 0), "snap_align":False,\
  56. "snap_normal":(0, 0, 0), "gpencil_strokes":False, \
  57. "cursor_transform":False, "texture_space":False,\
  58. "remove_on_cancel":False, "use_duplicated_keyframes":False,\
  59. "view2d_edge_pan":False, "release_confirm":False,\
  60. "use_accurate":False, "use_automerge_and_split":False})
  61. #comment
  62. """
  63. #bone3
  64. """
  65.  
・ブログ内関連リンク
選択する場合のスクリプトのリンク

>追記、3つの円柱とボーンを作成して、オートウェイトを設定するまでのスクリプト
8つ、6つ、4つのボーン、円柱は同じサイズ

以下スクリプト

円柱、ボーンを作成する関数とウェイト設定をする関数を作成した
  1. import os
  2. import bpy
  3. import math
  4. import copy
  5. import time
  6. #2024/10/9
  7. #print文はBlenderのメニューバーの Window > Toggle System Consoleを実行するとDOS窓が表示される
  8.  
  9. #make obj 円柱作成 Blender text ここでは日本語の入力はできないので、他で入力してコピペして
  10. #Next here 10/14
  11. #next code is 3 obj and 3 armatureBones. so make Function objAndBones(location,gDepth,gCountBones)
  12. def funcObjAndBones(mylocation,myDepth,myCountBones):
  13. #location=(0, 0, gDepth/2)
  14. loc=mylocation
  15. #円柱Vertices16,半径0.5m、Depth6m 座標:0,0,3m(Depth6m/2)
  16. #中心点をDepth6m/2 半分Z軸を上げる
  17. # location=(0, 0, 3)#z is 3m , Depth is 6m, its half size.
  18. bpy.ops.mesh.primitive_cylinder_add(vertices=16,radius=0.5, depth=myDepth, enter_editmode=False,\
  19. align='WORLD', location=loc, scale=(1, 1, 1))
  20. #CTR+R bunkatsu 16 cuts
  21. #Start edit mode
  22. bpy.ops.object.editmode_toggle()
  23. bpy.ops.mesh.loopcut_slide(MESH_OT_loopcut=
  24. {"number_cuts":16, "smoothness":0,\
  25. "falloff":'INVERSE_SQUARE', "object_index":0, "edge_index":15,\
  26. "mesh_select_mode_init":(True, False, False)},\
  27. TRANSFORM_OT_edge_slide={"value":0, "single_side":False,\
  28. "use_even":False, "flipped":False, \
  29. "use_clamp":True, "mirror":True, "snap":False, \
  30. "snap_elements":{'INCREMENT'}, "use_snap_project":False, \
  31. "snap_target":'CLOSEST', "use_snap_self":True, \
  32. "use_snap_edit":True, "use_snap_nonedit":True,\
  33. "use_snap_selectable":False, "snap_point":(0, 0, 0),\
  34. "correct_uv":True, "release_confirm":False, "use_accurate":False})
  35. bpy.ops.object.editmode_toggle()#from edit to OBJ mode
  36. # end edit mode
  37. #add bone 1
  38. #ボーンのlocationのZ軸は原点に戻す必要がある。
  39. loc=(mylocation[0],mylocation[1],mylocation[2]-myDepth/2)
  40. bpy.ops.object.armature_add(enter_editmode=False, align='WORLD', location=loc, \
  41. scale=(1, 1, myDepth/myCountBones)) #6/4=1.5 Z軸スケールがなんかうまくいってない2024/10/15
  42. # Edit mode start
  43. bpy.ops.object.editmode_toggle()
  44. #add bone2 to (gCountBones-1)
  45. #ボーンの増加は、大きい親ボーンを分割処理してもいいのかも。試してみて。2024/10/15
  46. #E key EXTRUDE add child bone
  47. if myCountBones < 2:
  48. myCountBones=2
  49. #range(num) is 0 to num-1. exp: num=9 then 012345678 , its 9 counts. not exist [number9] .
  50. for i in range(myCountBones):# range() is from 0 to (gcountBones-1), total count is [gCountBOnes].
  51. if i >= myCountBones-1:
  52. break
  53. else:
  54. bpy.ops.armature.extrude_move(ARMATURE_OT_extrude={"forked":False},\
  55. TRANSFORM_OT_translate={"value":(0, 0, myDepth/myCountBones),\
  56. "orient_type":'GLOBAL',\
  57. "orient_matrix":((1, 0, 0), (0, 1, 0), (0, 0, 1)),\
  58. "orient_matrix_type":'GLOBAL', "constraint_axis":(False, False, True),\
  59. "mirror":False, "use_proportional_edit":False,\
  60. "proportional_edit_falloff":'SMOOTH',\
  61. "proportional_size":1,\
  62. "use_proportional_connected":False,\
  63. "use_proportional_projected":False,\
  64. "snap":False, "snap_elements":{'INCREMENT'},\
  65. "use_snap_project":False, "snap_target":'CLOSEST',\
  66. "use_snap_self":True, "use_snap_edit":True,\
  67. "use_snap_nonedit":True, "use_snap_selectable":False,\
  68. "snap_point":(0, 0, 0), "snap_align":False,\
  69. "snap_normal":(0, 0, 0), "gpencil_strokes":False, \
  70. "cursor_transform":False, "texture_space":False,\
  71. "remove_on_cancel":False, "use_duplicated_keyframes":False,\
  72. "view2d_edge_pan":False, "release_confirm":False,\
  73. "use_accurate":False, "use_automerge_and_split":False})
  74. bpy.ops.object.editmode_toggle()
  75. #End Edit mode
  76. #end def
  77.  
  78. #円柱とボーンにウェイトを設定する。オブジェクト名を指定して1組だけ設定
  79. def funcAutomaticWeight(firstObjName,SecondObjName):
  80. #next 1個ずつ親子設定にしていく、できれば親子関係がすでに設定されていれば何もしないようにしたいが、よくわからない
  81. gFindOne=""
  82. gFindTwo=""
  83. #object mode にしないとオートウェイとが正しく動作しない
  84. print("now mode is ",bpy.context.mode) #editモードだったら、EDIT_ARMATURE のように出力される
  85. if bpy.context.mode == 'OBJECT':
  86. print("now OBJECT MODE")
  87. else:
  88. bpy.ops.object.editmode_toggle()#Objectモードに変更
  89. #2回ループは非効率的だけど、今はこれでいく 1組のオブジェクトとボーンをウェイト設定
  90. #Cylinder
  91. for obj in bpy.data.objects:
  92. if firstObjName in obj.name:
  93. print("find obj1")
  94. obj.select_set(True)
  95. gFindOne="ari"
  96. #Armature
  97. for obj in bpy.data.objects:
  98. if SecondObjName in obj.name:
  99. print("find obj2")
  100. obj.select_set(True)
  101. gFindTwo="ari"
  102.  
  103. #できれば、すでに親子関係・ウェイトモードが設定されているかを判別したいけど、わからない
  104. if gFindOne=="ari" and gFindTwo=="ari":
  105. print("add parent do")
  106. #bone weight Automatic Weight Ctr+P オブジェクトモードで実行する必要がある
  107. bpy.ops.object.parent_set(type='ARMATURE_AUTO')
  108. #end def
  109.  
  110. if __name__ == "__main__":
  111. #main GO
  112. #var
  113. gDepth=6# cylinder hight
  114. gCountBones=6# bone count over 2 number.limit count is [11 or 12]. by gDepth:6
  115. # 3Dカーソルの位置を元に戻す
  116. bpy.context.scene.cursor.location=(0.0,0.0,0.0)
  117. #円柱Vertices16,半径0.5m、Depth6m 座標:0,0,3m(Depth6m/2)
  118. testLocation=(0.0,0.0,gDepth/2) #x,y,z
  119. funcObjAndBones(testLocation,gDepth,8) #location,high,bonesCount
  120. funcAutomaticWeight("Cylinder","Armature")
  121. #2つめの円柱
  122. testLocation=(1.5,0.0,gDepth/2) #x,y,z
  123. funcObjAndBones(testLocation,gDepth,6) #location,high,bonesCount
  124. funcAutomaticWeight("Cylinder.001","Armature.001")
  125.  
  126. #3つめ
  127. testLocation=(3.0,0.0,gDepth/2) #x,y,z
  128. funcObjAndBones(testLocation,gDepth,4) #location,high,bonesCount
  129. funcAutomaticWeight("Cylinder.002","Armature.002")
  130.  
  131. #end for
  132. #comment
  133. """
  134. #bone3
  135. """
  136.  
>追記、2024/10/16 さらにPoseモード状態にしてWiggle2の設定をボーンに与える自動化スクリプトで楽をする。
 手間取った点は、ボーンは、Pose状態とArmature状態のそれぞれにボーンが存在する。そのためこの2つの状態が存在することに気づかないと間違った状態でのボーンをスクリプトで選択して、設定を与えてしまい期待した結果が表示されないとか、期待した動きが設定できないというジレンマに陥る。結果的にいろいろ試行錯誤やトライアンドエラーを試すことでブレンダーのPythonAPIの仕様がわかってくる。
以下は、上記のスクリプトに加え、Wiggle2アドオンの設定を加えることで揺れる動きを設定できた。

なお、スクリプトやPythonに詳しいわけではないので手本となるプログラムコードではないし無駄で不要コードも多い。エラー処理も入れていない。
スクリプトの構成、円柱を作成、ボーンを作成、ウェイトを設定、Wiggle2のボーン設定(Head,Tail)の順になる。3つしか円柱を作成していないけど、もっと増やしたいなら各パラメータを配列にして順番に取り出せるようにして、Forで作成したい数だけ増やすとよい。


ポーズモード、Head(根元)の設定 settingListOne(settingListTwo,settingListThree各配列)で値を設定し0番目がHeadでそれ以降がTailのStiffの値になる。

ポーズモード、尻尾側Tailの設定

以下スクリプト


  1. import os
  2. import bpy
  3. import math
  4. import copy
  5. import time
  6. #2024/10/9
  7. #print文はBlenderのメニューバーの Window > Toggle System Consoleを実行するとDOS窓が表示される
  8.  
  9. #make obj 円柱作成 Blender text ここでは日本語の入力はできないので、他で入力してコピペして
  10. #Next here 10/14
  11. #next code is 3 obj and 3 armatureBones. so make Function objAndBones(location,gDepth,gCountBones)
  12. def funcObjAndBones(mylocation,myDepth,myCountBones):
  13. #location=(0, 0, gDepth/2)
  14. loc=mylocation
  15. #円柱Vertices16,半径0.5m、Depth6m 座標:0,0,3m(Depth6m/2)
  16. #中心点をDepth6m/2 半分Z軸を上げる
  17. # location=(0, 0, 3)#z is 3m , Depth is 6m, its half size.
  18. bpy.ops.mesh.primitive_cylinder_add(vertices=16,radius=0.5, depth=myDepth, enter_editmode=False,\
  19. align='WORLD', location=loc, scale=(1, 1, 1))
  20. #CTR+R bunkatsu 16 cuts
  21. #Start edit mode
  22. bpy.ops.object.editmode_toggle()
  23. bpy.ops.mesh.loopcut_slide(MESH_OT_loopcut=
  24. {"number_cuts":16, "smoothness":0,\
  25. "falloff":'INVERSE_SQUARE', "object_index":0, "edge_index":15,\
  26. "mesh_select_mode_init":(True, False, False)},\
  27. TRANSFORM_OT_edge_slide={"value":0, "single_side":False,\
  28. "use_even":False, "flipped":False, \
  29. "use_clamp":True, "mirror":True, "snap":False, \
  30. "snap_elements":{'INCREMENT'}, "use_snap_project":False, \
  31. "snap_target":'CLOSEST', "use_snap_self":True, \
  32. "use_snap_edit":True, "use_snap_nonedit":True,\
  33. "use_snap_selectable":False, "snap_point":(0, 0, 0),\
  34. "correct_uv":True, "release_confirm":False, "use_accurate":False})
  35. bpy.ops.object.editmode_toggle()#from edit to OBJ mode
  36. # end edit mode
  37. #add bone 1
  38. #ボーンのlocationのZ軸は原点に戻す必要がある。
  39. loc=(mylocation[0],mylocation[1],mylocation[2]-myDepth/2)
  40. bpy.ops.object.armature_add(enter_editmode=False, align='WORLD', location=loc, \
  41. scale=(1, 1, myDepth/myCountBones)) #6/4=1.5 Z軸スケールがなんかうまくいってない2024/10/15
  42. # Edit mode start
  43. bpy.ops.object.editmode_toggle()
  44. #add bone2 to (gCountBones-1)
  45. #ボーンの増加は、大きい親ボーンを分割処理してもいいのかも。試してみて。2024/10/15
  46. #E key EXTRUDE add child bone
  47. if myCountBones < 2:
  48. myCountBones=2
  49. #range(num) is 0 to num-1. exp: num=9 then 012345678 , its 9 counts. not exist [number9] .
  50. for i in range(myCountBones):# range() is from 0 to (gcountBones-1), total count is [gCountBOnes].
  51. if i >= myCountBones-1:
  52. break
  53. else:
  54. bpy.ops.armature.extrude_move(ARMATURE_OT_extrude={"forked":False},\
  55. TRANSFORM_OT_translate={"value":(0, 0, myDepth/myCountBones),\
  56. "orient_type":'GLOBAL',\
  57. "orient_matrix":((1, 0, 0), (0, 1, 0), (0, 0, 1)),\
  58. "orient_matrix_type":'GLOBAL', "constraint_axis":(False, False, True),\
  59. "mirror":False, "use_proportional_edit":False,\
  60. "proportional_edit_falloff":'SMOOTH',\
  61. "proportional_size":1,\
  62. "use_proportional_connected":False,\
  63. "use_proportional_projected":False,\
  64. "snap":False, "snap_elements":{'INCREMENT'},\
  65. "use_snap_project":False, "snap_target":'CLOSEST',\
  66. "use_snap_self":True, "use_snap_edit":True,\
  67. "use_snap_nonedit":True, "use_snap_selectable":False,\
  68. "snap_point":(0, 0, 0), "snap_align":False,\
  69. "snap_normal":(0, 0, 0), "gpencil_strokes":False, \
  70. "cursor_transform":False, "texture_space":False,\
  71. "remove_on_cancel":False, "use_duplicated_keyframes":False,\
  72. "view2d_edge_pan":False, "release_confirm":False,\
  73. "use_accurate":False, "use_automerge_and_split":False})
  74. bpy.ops.object.editmode_toggle()
  75. #End Edit mode
  76. #end def
  77.  
  78. #円柱とボーンにウェイトを設定する。オブジェクト名を指定して1組だけ設定
  79. def funcAutomaticWeight(firstObjName,SecondObjName):
  80. #next 1個ずつ親子設定にしていく、できれば親子関係がすでに設定されていれば何もしないようにしたいが、よくわからない
  81. gFindOne=""
  82. gFindTwo=""
  83. tmpObj=""
  84. #object mode にしないとオートウェイとが正しく動作しない
  85. print("now mode is ",bpy.context.mode) #editモードだったら、EDIT_ARMATURE のように出力される
  86. if bpy.context.mode == 'OBJECT':
  87. print("now OBJECT MODE")
  88. else:
  89. bpy.ops.object.editmode_toggle()#Objectモードに変更
  90. #2回ループは非効率的だけど、今はこれでいく 1組のオブジェクトとボーンをウェイト設定
  91. #Cylinder
  92. for obj in bpy.data.objects:
  93. if firstObjName in obj.name:
  94. print("find obj1")
  95. tmpObj=obj
  96. obj.select_set(True)
  97. gFindOne="ari"
  98. #Armature
  99. for obj in bpy.data.objects:
  100. if SecondObjName in obj.name:
  101. print("find obj2")
  102. obj.select_set(True)
  103. gFindTwo="ari"
  104.  
  105. #できれば、すでに親子関係・ウェイトモードが設定されているかを判別したいけど、わからない
  106. if gFindOne=="ari" and gFindTwo=="ari":
  107. print("add parent do")
  108. #bone weight Automatic Weight Ctr+P オブジェクトモードで実行する必要がある
  109. bpy.ops.object.parent_set(type='ARMATURE_AUTO')
  110. else:
  111. print("いずれか一方または両方選択できませんでした")
  112.  
  113. tmpObj.select_set(False)#Cylinder解除
  114. bpy.ops.object.editmode_toggle()#Editモードに変更
  115. #end def
  116.  
  117. def funcSetWiggle2(arm,settingList):#armはアーマチュア名
  118. #アドオン wiggle2がインストールされていることが前提
  119. #settingListOne は、設定のリスト、パラメータ配列、ボーンの数によって設定は個別に異なる
  120. #head:root, tail:尻尾揺れる
  121. bpy.ops.object.mode_set(mode='POSE')
  122.  
  123. print("Making Wiggle2")
  124. if len(settingList) < 1:
  125. print("配列のパラメータが足りません")
  126. #2024/10/15 14:36
  127. #ArmatureからPoseのBone親を探して、子どもに設定する.
  128. gFindOne=""
  129. gFindTwo=""
  130. gWiggleBoneCount=0
  131. #print("settingList[gWiggleBoneCount] :"+str(settingList[gWiggleBoneCount]))
  132. boneStrTmp="Bone.000"
  133. listCount=len(settingList)
  134. for obj in bpy.data.objects:
  135. if arm in obj.name:
  136. #print("find arm")
  137. obj.select_set(True)
  138. #gFindOne="ari"
  139. #Editモードに変更 pose モードにするためだけど効き目がないので無駄なコードかも
  140. for subbone in obj.pose.bones:
  141. print("bone::"+subbone.name)
  142. if "Bone" == subbone.name and gWiggleBoneCount == 0:# Bone in nameにすると含まれるになる
  143. print ("bone name:" + str(subbone.name))
  144. #次はここから、
  145. #☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
  146. #2024/10/15 うまくいってない
  147. #理由がわかった。ポーズモードでボーンに設定を与えるから、
  148. #本来は、ポーズモードで、Amature>Pose>Bone、、、Bone007に対して設定を与える。
  149. #正しくできなかったのは、Objedtモード状態の  Amature>Armature.022>Bone、、、Bone007に設定してる気がする。
  150. #最後に誤りの一番の理由は、Selectしたままにしたので、その値が最後の値で上書きされてしまった。selectを解除が必要だった
  151. #2024/10/15
  152. #subbone.select_set(True) #ボーンではエラーになるamt.pose.bones['Bone'].bone.select = True
  153. subbone.bone.select=True
  154. bpy.context.scene.wiggle_enable = True
  155. bpy.context.active_pose_bone.wiggle_head = True #'NoneType' object has no attribute 'wiggle_head' ポーズモードになっていないとエラー
  156. bpy.context.active_pose_bone.wiggle_stiff_head = settingList[gWiggleBoneCount]
  157. bpy.context.active_pose_bone.wiggle_tail = False
  158. subbone.bone.select=False #解除してなかったので、上書きされた
  159. print("パラメータ:"+str(settingList[gWiggleBoneCount]) )
  160. gWiggleBoneCount=1
  161. #他にも設定があるので別の機会に試す
  162. else:
  163. #以下のIF部分は再度構成したほうがよい。たぶん入れ子の構想がまずい気がする。もっとスマートな書き方がある。2024/10/15
  164. if gWiggleBoneCount >=1: #少なくとも親ボーン[0]が見つからないと処理しない。子ボーンから001になる
  165. boneStrTmpCount=len(boneStrTmp)
  166. boneStr=""
  167. if gWiggleBoneCount < 10:#1桁の場合
  168. #print("ボーン1桁")
  169. #boneStrTmpの最後の1文字を数字に置き換える
  170. boneStr=boneStrTmp[0:boneStrTmpCount-1]+str(gWiggleBoneCount)
  171. #print("ボーン名"+boneStr)
  172. elif gWiggleBoneCount >= 10 and gWiggleBoneCount < 100:
  173. print("ボーン2桁")
  174. #boneStrTmpの最後の2文字を数字に置き換える
  175. boneStr=boneStrTmp[0:boneStrTmpCount-2]+str(gWiggleBoneCount)#ここは確認してない
  176. elif gWiggleBoneCount >= 100:
  177. print("100以上は対応できません。")
  178. break
  179.  
  180. if boneStr == subbone.name:
  181. #子ボーン選択 forで対応。もしsettingListの要素数が足りない場合は、最後の値を使用する
  182. #2024/10/15
  183. #subbone.select_set(True)
  184. #bpy.ops.object.mode_set(mode='POSE')
  185. subbone.bone.select=True
  186. bpy.context.active_pose_bone.wiggle_tail = True
  187. #settingListの数が、ボーンの数より小さいときは、最後の値をそのまま使う
  188. #2024/10/15
  189. if (listCount-1) < gWiggleBoneCount:
  190. bpy.context.active_pose_bone.wiggle_stiff = settingList[-1]#最後の値を挿入
  191. print("settingListの数が合っていないので最後の値を使用しました")
  192. else:
  193. bpy.context.active_pose_bone.wiggle_stiff = settingList[gWiggleBoneCount]
  194. print(boneStr+":パラメータ:"+str(settingList[gWiggleBoneCount]) )
  195. gWiggleBoneCount+=1
  196. subbone.bone.select=False #設定したら、選択を解除する
  197. #end def
  198.  
  199. if __name__ == "__main__":
  200. #main GO
  201. #var
  202. gDepth=6# cylinder hight
  203. gCountBones=6# bone count over 2 number.limit count is [11 or 12]. << by gDepth:6
  204. # 3Dカーソルの位置を元に戻す
  205. bpy.context.scene.cursor.location=(0.0,0.0,0.0)
  206. #円柱Vertices16,半径0.5m、Depth6m 座標:0,0,3m(Depth6m/2)
  207. testLocation=(0.0,0.0,gDepth/2) #x,y,z
  208. funcObjAndBones(testLocation,gDepth,8) #location,high,bonesCountボーンの数
  209. funcAutomaticWeight("Cylinder","Armature")
  210. settingListOne=[400,500,600,700,810,820,830,860]#ボーンの数分必要になる
  211. funcSetWiggle2("Armature",settingListOne) #現在作業中
  212. bpy.ops.object.mode_set(mode='OBJECT')
  213.  
  214. #2つめの円柱
  215. testLocation=(1.5,0.0,gDepth/2) #x,y,z
  216. funcObjAndBones(testLocation,gDepth,6) #location,high,bonesCountボーンの数
  217. funcAutomaticWeight("Cylinder.001","Armature.001")
  218. settingListTwo=[410,800,800,800,800,880]
  219. funcSetWiggle2("Armature.001",settingListTwo)
  220.  
  221. #3つめ
  222. testLocation=(3.0,0.0,gDepth/2) #x,y,z
  223. funcObjAndBones(testLocation,gDepth,4) #location,high,bonesCountボーンの数
  224. funcAutomaticWeight("Cylinder.002","Armature.002")
  225. settingListThree=[420,800,800,810]
  226. funcSetWiggle2("Armature.002",settingListThree)
  227. #end main
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  

このブログの人気の投稿

国税庁確定申告でエラーになったところ株式譲渡が赤字の場合には、配当を申告不要とすることはできません

メモ、BlenderPythonスクリプトで参考になるオブジェクトや頂点の選択ツリー選択スクリプトリンクメモ

楽天証券、信用取引口座から楽天FX口座へ振替手順