3 from . import vertexarray
5 from ..pymeshio import englishmap
9 __slots__=['name', 'type', 'offsets']
10 def __init__(self, name, type):
15 def add(self, index, offset):
16 self.offsets.append((index, offset))
19 self.offsets.sort(key=lambda e: e[0])
22 return "<Morph %s>" % self.name
30 class DefaultMatrial(object):
34 self.diffuse_color=[1, 1, 1]
37 self.specular_toon_size=0
38 self.specular_hardness=5
39 self.specular_color=[1, 1, 1]
41 self.mirror_color=[1, 1, 1]
43 self.subsurface_scattering=SSS()
48 class OneSkinMesh(object):
49 __slots__=['vertexArray', 'morphList', 'rigidbodies', 'constraints', 'armatureObj']
51 self.vertexArray=vertexarray.VertexArray()
58 return "<OneSkinMesh %s, morph:%d>" % (
62 def build(self, node):
63 ############################################################
64 # search armature modifier
65 ############################################################
66 for m in node.o.modifiers:
67 if bl.modifier.isType(m, 'ARMATURE'):
68 armatureObj=bl.modifier.getArmatureObject(m)
69 if not self.armatureObj:
70 self.armatureObj=armatureObj
71 elif self.armatureObj!=armatureObj:
72 print("warning! found multiple armature. ignored.",
75 if node.o.type.upper()=='MESH':
78 for child in node.children:
81 def addMesh(self, obj):
82 if not bl.object.isVisible(obj):
87 self.__constraint(obj)
89 def __getWeightMap(self, obj, mesh):
93 def setWeight(i, name, w):
96 if i in secondWeightMap:
98 if w<secondWeightMap[i][1]:
100 elif w<weightMap[i][1]:
102 secondWeightMap[i]=(name, w)
105 weightMap[i]=(name, w)
107 if w>weightMap[i][1]:
109 secondWeightMap[i]=weightMap[i]
110 weightMap[i]=(name, w)
112 secondWeightMap[i]=(name, w)
114 weightMap[i]=(name, w)
116 # ToDo bone weightと関係ないvertex groupを除外する
117 for i, v in enumerate(mesh.vertices):
120 setWeight(i, obj.vertex_groups[g.group].name, g.weight)
123 setWeight(i, obj.vertex_groups[0].name, 1)
129 for i in range(len(mesh.vertices)):
130 if i in secondWeightMap:
131 secondWeightMap[i]=(secondWeightMap[i][0], 1.0-weightMap[i][1])
133 weightMap[i]=(weightMap[i][0], 1.0)
134 secondWeightMap[i]=("", 0)
136 print("no weight vertex")
138 secondWeightMap[i]=("", 0)
140 return weightMap, secondWeightMap
142 def __processFaces(self, obj_name, mesh, weightMap, secondWeightMap):
143 default_material=DefaultMatrial()
145 for i, face in enumerate(mesh.faces):
146 faceVertexCount=bl.face.getVertexCount(face)
148 material=mesh.materials[bl.face.getMaterialIndex(face)]
149 except IndexError as e:
150 material=default_material
151 v=[mesh.vertices[index] for index in bl.face.getVertices(face)]
152 uv=bl.mesh.getFaceUV(
153 mesh, i, face, bl.face.getVertexCount(face))
155 if faceVertexCount==3:
157 self.vertexArray.addTriangle(
158 obj_name, material.name,
165 bl.vertex.getNormal(v[2]),
166 bl.vertex.getNormal(v[1]),
167 bl.vertex.getNormal(v[0]),
171 weightMap[v[2].index][0],
172 weightMap[v[1].index][0],
173 weightMap[v[0].index][0],
174 secondWeightMap[v[2].index][0],
175 secondWeightMap[v[1].index][0],
176 secondWeightMap[v[0].index][0],
177 weightMap[v[2].index][1],
178 weightMap[v[1].index][1],
179 weightMap[v[0].index][1]
181 elif faceVertexCount==4:
183 self.vertexArray.addTriangle(
184 obj_name, material.name,
191 bl.vertex.getNormal(v[2]),
192 bl.vertex.getNormal(v[1]),
193 bl.vertex.getNormal(v[0]),
197 weightMap[v[2].index][0],
198 weightMap[v[1].index][0],
199 weightMap[v[0].index][0],
200 secondWeightMap[v[2].index][0],
201 secondWeightMap[v[1].index][0],
202 secondWeightMap[v[0].index][0],
203 weightMap[v[2].index][1],
204 weightMap[v[1].index][1],
205 weightMap[v[0].index][1]
207 self.vertexArray.addTriangle(
208 obj_name, material.name,
215 bl.vertex.getNormal(v[0]),
216 bl.vertex.getNormal(v[3]),
217 bl.vertex.getNormal(v[2]),
221 weightMap[v[0].index][0],
222 weightMap[v[3].index][0],
223 weightMap[v[2].index][0],
224 secondWeightMap[v[0].index][0],
225 secondWeightMap[v[3].index][0],
226 secondWeightMap[v[2].index][0],
227 weightMap[v[0].index][1],
228 weightMap[v[3].index][1],
229 weightMap[v[2].index][1]
232 def __mesh(self, obj):
233 if bl.RIGID_SHAPE_TYPE in obj:
235 if bl.CONSTRAINT_A in obj:
238 bl.message("export: %s" % obj.name)
240 # メッシュのコピーを生成してオブジェクトの行列を適用する
241 copyMesh, copyObj=bl.object.duplicate(obj)
242 copyObj.name="tmp_object"
243 if len(copyMesh.vertices)>0:
245 copyMesh.transform(obj.matrix_world)
248 for m in [m for m in copyObj.modifiers]:
249 if m.type=='SOLIDFY':
251 elif m.type=='ARMATURE':
253 elif m.type=='MIRROR':
254 bpy.ops.object.modifier_apply(modifier=m.name)
258 weightMap, secondWeightMap=self.__getWeightMap(copyObj, copyMesh)
259 self.__processFaces(obj.name, copyMesh, weightMap, secondWeightMap)
260 bl.object.delete(copyObj)
262 def createEmptyBasicSkin(self):
263 self.__getOrCreateMorph('base', 0)
265 def __skin(self, obj):
266 if not bl.object.hasShapeKey(obj):
270 blenderMesh=bl.object.getData(obj)
274 vg=bl.object.getVertexGroup(obj, bl.MMD_SHAPE_GROUP_NAME)
278 for b in bl.object.getShapeKeys(obj):
279 if b.name==bl.BASE_SHAPE_NAME:
280 baseMorph=self.__getOrCreateMorph('base', 0)
285 v=bl.shapekey.getByIndex(b, index)
286 pos=[v[0], v[1], v[2]]
288 indices=self.vertexArray.getMappedIndex(obj.name, index)
289 for attribute, i in indices.items():
294 baseMorph.add(i, pos)
295 indexRelativeMap[i]=relativeIndex
300 #print(basis.name, len(baseMorph.offsets))
302 if len(baseMorph.offsets)==0:
306 for b in bl.object.getShapeKeys(obj):
307 if b.name==bl.BASE_SHAPE_NAME:
311 morph=self.__getOrCreateMorph(b.name, 4)
313 for index, src, dst in zip(
314 range(len(blenderMesh.vertices)),
315 bl.shapekey.get(basis),
317 offset=[dst[0]-src[0], dst[1]-src[1], dst[2]-src[2]]
318 if offset[0]==0 and offset[1]==0 and offset[2]==0:
321 indices=self.vertexArray.getMappedIndex(obj.name, index)
322 for attribute, i in indices.items():
326 morph.add(indexRelativeMap[i], offset)
327 assert(len(morph.offsets)<len(baseMorph.offsets))
330 original=self.morphList[:]
332 for i, v in enumerate(englishmap.skinMap):
336 return len(englishmap.skinMap)
337 self.morphList.sort(key=getIndex)
339 def __rigidbody(self, obj):
340 if not bl.RIGID_SHAPE_TYPE in obj:
342 self.rigidbodies.append(obj)
344 def __constraint(self, obj):
345 if not bl.CONSTRAINT_A in obj:
347 self.constraints.append(obj)
349 def __getOrCreateMorph(self, name, type):
350 for m in self.morphList:
354 self.morphList.append(m)
357 def getVertexCount(self):
358 return len(self.vertexArray.positions)