3 from ..pymeshio import englishmap
6 class IKSolver(object):
7 __slots__=['target', 'effector', 'length', 'iterations', 'weight']
8 def __init__(self, target, effector, length, iterations, weight):
10 self.effector=effector
12 self.iterations=iterations
17 __slots__=['index', 'name', 'ik_index',
18 'pos', 'tail', 'parent_index', 'tail_index', 'type', 'isConnect']
19 def __init__(self, name, pos, tail, isConnect):
24 self.parent_index=None
27 self.isConnect=isConnect
30 def __eq__(self, rhs):
31 return self.index==rhs.index
34 return "<Bone %s %d>" % (self.name, self.type)
37 class BoneBuilder(object):
38 __slots__=['bones', 'boneMap', 'ik_list', 'bone_groups',]
45 def getBoneGroup(self, bone):
46 for i, g in enumerate(self.bone_groups):
50 print('no gorup', bone)
53 def build(self, armatureObj):
57 bl.message("build skeleton")
58 armature=bl.object.getData(armatureObj)
63 for g in bl.object.boneGroups(armatureObj):
64 self.bone_groups.append((g.name, []))
69 for b in armature.bones.values():
73 bl.bone.getHeadLocal(b),
74 bl.bone.getTailLocal(b),
77 self.__getBone(bone, b)
79 for b in armature.bones.values():
81 self.__checkConnection(b, None)
86 pose = bl.object.getPose(armatureObj)
87 for b in pose.bones.values():
91 self.__assignBoneGroup(b, b.bone_group)
92 for c in b.constraints:
93 if bl.constraint.isIKSolver(c):
97 target=self.__boneByName(bl.constraint.ikTarget(c))
104 link=self.__boneByName(b.name)
109 chainLength=bl.constraint.ikChainLen(c)
110 for i in range(chainLength):
112 chainBone=self.__boneByName(e.name)
114 chainBone.ik_index=target.index
117 IKSolver(target, link, chainLength,
118 int(bl.constraint.ikItration(c) * 0.1),
119 bl.constraint.ikRotationWeight(c)
129 for i, v in enumerate(englishmap.boneMap):
130 if v[0]==ik.target.name:
132 return len(englishmap.boneMap)
133 self.ik_list.sort(key=getIndex)
135 def __assignBoneGroup(self, poseBone, boneGroup):
137 for g in self.bone_groups:
138 if g[0]==boneGroup.name:
139 g[1].append(poseBone.name)
141 def __checkConnection(self, b, p):
142 if bl.bone.isConnected(b):
143 parent=self.__boneByName(p.name)
144 parent.isConnect=True
147 self.__checkConnection(c, b)
153 boneMap=englishmap.boneMap
154 original=self.bones[:]
156 for i, k_v in enumerate(boneMap):
157 if k_v[0]==bone.name:
162 self.bones.sort(key=getIndex)
165 for i, b in enumerate(self.bones):
166 src=original.index(b)
169 b.index=sortMap[b.index]
171 b.parent_index=sortMap[b.parent_index]
173 b.tail_index=sortMap[b.tail_index]
175 b.ik_index=sortMap[b.ik_index]
183 if b.parent_index==None:
186 if b.type==6 or b.type==7:
188 parent=self.bones[b.parent_index]
189 #print('parnet', parent.name)
190 parent.tail_index=b.index
193 if b.tail_index==None:
198 def getIndex(self, bone):
199 for i, b in enumerate(self.bones):
204 def indexByName(self, name):
209 return self.getIndex(self.__boneByName(name))
213 def __boneByName(self, name):
214 return self.boneMap[name]
216 def __getBone(self, parent, b):
217 if len(b.children)==0:
221 for i, c in enumerate(b.children):
223 bl.bone.getHeadLocal(c),
224 bl.bone.getTailLocal(c),
225 bl.bone.isConnected(c))
228 bone.parent_index=parent.index
230 if bone.isConnect or (not parent.tail_index and parent.tail==bone.pos):
231 parent.tail_index=bone.index
232 self.__getBone(bone, c)
234 def __addBone(self, bone):
235 bone.index=len(self.bones)
236 self.bones.append(bone)
237 self.boneMap[bone.name]=bone