在搅拌机中,我想将整个骨骼结构替换为空。考虑这个模型骨树:
应将整个结构转换为空树,并保留名称和父子顺序:
(由于我想您已经明白了,所以我刚刚在这里画了第一张图)
注意:此图片中的动画不有趣!
目前,我正在阅读所有骨骼,将它们保存到一些2D python列表中,然后尝试通过递归遍历该数组来重新创建带有空的整个结构:
class ReplaceBones(bpy.types.Operator):
bl_label = "Replace Bones"
bl_idname = "replace.bones"
bl_description = "Replaces all bones with empties."
def execute(self, context):
#Set mode to 'OBJECT'
if not bpy.context.mode == 'OBJECT':
bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
#Deselect everything
bpy.ops.object.select_all(action='DESELECT')
#Check if Root exists
if 'Root' in bpy.context.scene.objects:
#Switch to Root
root = bpy.data.objects['Root']
bpy.context.scene.objects.active = root
#Get all Bones
contObj = bpy.context.object
bones = contObj.data
#Set mode to EDIT to access edit_bones
bpy.ops.object.mode_set(mode='EDIT')
boneList = []
childList = []
#Loop through bones
for bone in bones.edit_bones:
#boneList.append(bone.name)
boneList.append(childList)
childList = [bone.name]
for child in bone.children:
childList.append(child.name)
#test
print()
print("WHOLE LIST")
for bone in boneList:
print(bone)
print(".......length: " + str(len(bone)))
print()
#Set mode back to OBJECT
bpy.ops.object.mode_set(mode='OBJECT')
#Add Empties
self.recursiveAddEmpties(context, boneList, 'Root', 1)
else:
#Info pop up in blender
self.report({'INFO'}, "No Root found! Forgot to import model?")
return{"FINISHED"}
递归演练:
def recursiveAddEmpties(self, context, bones, activeObj, index):
head = bones[index][0]
children = bones[index]
print()
print("Recursion head: " + head)
print("Recursion children: " + str(children))
print("Recursion children len: " + str(len(children)))
print("index: " + str(index))
print()
#add head
if index == 1:
bpy.ops.object.empty_add(type='PLAIN_AXES')
bpy.context.object.name = head
emptyHead = bpy.context.object
if not len(children) == 1:
root = bpy.data.objects[activeObj]
bpy.context.scene.objects.active = root
print("Active object: " + str(bpy.context.scene.objects.active))
#add childs
for child in children:
if not child == head:
print("Active child: " + child)
bpy.ops.object.empty_add(type='PLAIN_AXES')
childObj = bpy.context.object
bpy.context.object.name = child
childObj.parent = emptyHead
index += 1
print("index: " + str(index))
if not index == len(bones) - 1:
self.recursiveAddEmpties(context, bones, head, index)
数组本身看起来像这样:
因此,基本上,它以一种方式表示树结构,其中包含子级(子树)的“头”始终位于索引0,除非仅剩一根骨头(例如['Root Ponytail1Nub'])>
递归函数以某种方式起作用。从某种意义上说,它至少增加了所有头。但是,一旦完成了一个人的第一个递归级别,就无法正确添加子级。
结果如下:
现在我有点知道问题可能出在哪里。我不断增加数组索引,直到超出范围为止,然后进行下一个递归级别:
index += 1
if not index == len(bones) - 1:
self.recursiveAddEmpties(context, bones, head, index)
这很有效,直到必须像L_Clavicle这样选择子树的下一个树头时才是子树。
看起来主结构正确构建,但是子树有点混乱。我试图实现一个功能来搜索下一个出现的头部,基本上是将索引设置为此列表中子数组的下一个索引:
index = self.getHeadIndex(context, index, head, bones)
if not index == len(bones) - 1:
self.recursiveAddEmpties(context, bones, head, index)
def getHeadIndex(self, context, index, head, bones):
#try to find index of next occurance of head in bone list
print("Trying to find index. Actual index: " + str(index))
print("for head: " + str(head))
#start = index + 1
start = index + 1
if not start > len(bones) - 1:
print("start: " + str(start))
for i in range(start, len(bones)):
children = bones[i]
print("i: " + str(i))
for child in children:
print("child: " + child)
if head == child:
print("index found at " + str(i))
return i
else:
print("index not found. returning " + str(index))
return index
但是它导致索引== None错误或无穷递归。
这一切的底线是我认为主要的问题是,我的递归函数有效,其方式是直到下一个子树被行走之前,索引都会增加,但是当下一个孩子被选中并且是树的头部时,下一个子树“索引+ = 1”将导致问题。
也许有人可以在这里启发我:)。