OSDN Git Service

fix pmd. fix mqo.
[meshio/meshio.git] / swig / blender / bl25.py
1 # coding: utf-8
2 import bpy
3 import mathutils
4
5 import os
6 import sys
7 import time
8 import functools
9
10\e$B%U%!%$%k%7%9%F%`$NJ8;z%3!<%I\e(B
11\e$B2~B$HG$H$N6&MQ$N$?$a\e(B
12 FS_ENCODING=sys.getfilesystemencoding()
13 if os.path.exists(os.path.dirname(sys.argv[0])+"/utf8"):
14     INTERNAL_ENCODING='utf-8'
15 else:
16     INTERNAL_ENCODING=FS_ENCODING
17
18
19 ###############################################################################
20 # ProgressBar
21 ###############################################################################
22 class ProgressBar(object):
23     def __init__(self, base):
24         print("#### %s ####" % base)
25         self.base=base
26         self.start=time.time() 
27         self.set('<start>', 0)
28
29     def advance(self, message, progress):
30         self.progress+=float(progress)
31         self._print(message)
32
33     def set(self, message, progress):
34         self.progress=float(progress)
35         self._print(message)
36
37     def _print(self, message):
38         print(message)
39         message="%s: %s" % (self.base, message)
40         #Blender.Window.DrawProgressBar(self.progress, message)
41
42     def finish(self):
43         self.progress=1.0
44         message='finished in %.2f sec' % (time.time()-self.start)
45         self.set(message, 1.0)
46
47 def progress_start(base):
48     global progressBar
49     progressBar=ProgressBar(base)
50
51 def progress_finish():
52     global progressBar
53     progressBar.finish()
54
55 def progress_print(message, progress=0.05):
56     global progressBar
57     progressBar.advance(message, progress)
58
59 def progress_set(message, progress):
60     global progressBar
61     progressBar.set(message, progress)
62
63
64 ###############################################################################
65 class Writer(object):
66     def __init__(self, path, encoding):
67         self.io=open(path, "wb")
68         self.encoding=encoding
69
70     def write(self, s):
71         self.io.write(s.encode(self.encoding))
72
73     def flush(self):
74         self.io.flush()
75
76     def close(self):
77         self.io.close()
78
79 ###############################################################################
80 def createEmptyObject(scene, name):
81     empty=bpy.data.objects.new(name, None)
82     scene.objects.link(empty)
83     return empty
84
85 def createMaterial(name):
86     material = bpy.data.materials.new(name)
87     return material
88
89 def createMqoMaterial(m):
90     material = bpy.data.materials.new(m.getName())
91     material.diffuse_color=[m.color.r, m.color.g, m.color.b]
92     material.alpha=m.color.a
93     material.diffuse_intensity=m.diffuse
94     # temporary
95     material.emit=1.0
96     return material
97
98 def createPmdMaterial(m):
99     material = bpy.data.materials.new("Material")
100     material.diffuse_shader='TOON'
101     material.specular_shader='TOON'
102     material.diffuse_color=([m.diffuse.r, m.diffuse.g, m.diffuse.b])
103     material.alpha=m.diffuse.a
104     material.specular_hardness=int(m.shinness)
105     material.specular_color=([m.specular.r, m.specular.g, m.specular.b])
106     material.mirror_color=([m.ambient.r, m.ambient.g, m.ambient.b])
107     material.subsurface_scattering.enabled=True if m.flag==1 else False
108     # temporary
109     material.emit=1.0
110     return material
111
112 def createTexture(path):
113     texture=bpy.data.textures.new(os.path.basename(path))
114     texture.type='IMAGE'
115     texture=texture.recast_type()
116     image=bpy.data.images.load(path)
117     texture.image=image
118     texture.mipmap = True
119     texture.interpolation = True
120     texture.use_alpha = True
121     return texture, image
122
123
124 def materialAddTexture(material, texture):
125     #material.add_texture(texture, "UV", {"COLOR", "ALPHA"})
126     material.add_texture(texture, "UV", "COLOR")
127
128
129 def meshAddMaterial(mesh, material):
130     mesh.add_material(material)
131
132
133 def createMesh(scene, name):
134     mesh=bpy.data.meshes.new("Mesh")
135     mesh_object= bpy.data.objects.new(name, mesh)
136     scene.objects.link(mesh_object)
137     return mesh, mesh_object
138
139
140 def objectMakeParent(parent, child):
141     child.parent=parent
142
143
144 def meshAddMqoGeometry(mesh, o, materials, imageMap, scale):
145     # count triangle and quadrangle
146     faceCount=0
147     for f in o.faces:
148         if f.index_count==3 or f.index_count==4:
149             faceCount+=1
150     mesh.add_geometry(len(o.vertices), 0, faceCount)
151
152     # add vertex
153     unpackedVertices=[]
154     for v in o.vertices:
155         # convert right-handed y-up to right-handed z-up
156         unpackedVertices.extend(
157                 (scale*v.x, scale*-v.z, scale*v.y))
158     mesh.verts.foreach_set("co", unpackedVertices)
159
160     # add face
161     unpackedFaces = []
162     usedMaterial=set()
163
164     def getFace(f):
165         face = []
166         for i in range(f.index_count):
167             face.append(f.getIndex(i))
168         return face
169
170     for f in o.faces:
171         face=getFace(f)
172         if len(face) != 3 and len(face) != 4:
173             print("{0} vertices in face.".format(len(face)))
174             continue
175
176         if len(face) == 4:
177             if face[3] == 0:
178                 # rotate indices if the 4th is 0
179                 face = [face[3], face[0], face[1], face[2]]
180         elif len(face) == 3:
181             if face[2] == 0:
182                 # rotate indices if the 3rd is 0
183                 face = [face[2], face[0], face[1], 0]
184             else:
185                 face.append(0)
186
187         unpackedFaces.extend(face)
188         usedMaterial.add(f.material_index)
189     try:
190         mesh.faces.foreach_set("verts_raw", unpackedFaces)
191     except:
192         #print([getFace(f) for f in o.faces])
193         print("fail to mesh.faces.foreach_set")
194         return
195
196     # add material
197     meshMaterialMap={}
198     materialIndex=0
199     for i in usedMaterial:
200         mesh.add_material(materials[i])
201         meshMaterialMap[i]=materialIndex
202         materialIndex+=1
203
204     # each face
205     mesh.add_uv_texture()
206     for mqo_face, blender_face, uv_face in zip(
207             o.faces, mesh.faces, mesh.uv_textures[0].data):
208         if mqo_face.index_count<3:
209             continue
210         blender_face.material_index=meshMaterialMap[mqo_face.material_index]
211         if mqo_face.index_count>=3:
212             uv_face.uv1=[mqo_face.getUV(0).x, 1.0-mqo_face.getUV(0).y]
213             uv_face.uv2=[mqo_face.getUV(1).x, 1.0-mqo_face.getUV(1).y]
214             uv_face.uv3=[mqo_face.getUV(2).x, 1.0-mqo_face.getUV(2).y]
215             if mqo_face.index_count==4:
216                 uv_face.uv4=[
217                         mqo_face.getUV(3).x, 1.0-mqo_face.getUV(3).y]
218         if materials[mqo_face.material_index] in imageMap:
219             uv_face.image=imageMap[mqo_face.material_index]
220             uv_face.tex=True
221
222     mesh.update()
223
224 def getTexture(m, dirname):
225     tex=""
226     aplane=""
227     # texture
228     for slot in m.texture_slots:
229         if slot and slot.texture:
230             texture=slot.texture
231             if  texture.type=="IMAGE":
232                 image=texture.image
233                 if not image:
234                     continue
235                 imagePath=image.filename
236                 if len(dirname)>0 and imagePath.startswith(dirname):
237                     # \e$BAjBP%Q%9$KJQ49$9$k\e(B
238                     imagePath=imagePath[len(dirname)+1:len(imagePath)]
239                 #imagePath=Blender.sys.expandpath(
240                 #        imagePath).replace("\\", '/')
241                 if slot.map_colordiff:
242                     tex=" tex(\"%s\")" % imagePath
243                 elif slot.map_alpha:
244                     aplane=" aplane(\"%s\")" % imagePath
245     return tex, aplane
246
247 def objectDuplicate(scene, obj):
248     bpy.ops.object.select_all(action='DESELECT')
249     obj.selected=True
250     scene.objects.active=obj
251     bpy.ops.object.duplicate()
252     dumy=scene.objects.active
253     bpy.ops.object.rotation_apply()
254     bpy.ops.object.scale_apply()
255     bpy.ops.object.location_apply()
256     return dumy.data, dumy
257
258 def objectDelete(scene, obj):
259     scene.objects.unlink(obj)
260
261 def faceVertexCount(face):
262     return len(face.verts)
263
264 def faceVertices(face):
265     return face.verts[:]
266
267 def meshHasUV(mesh):
268     return mesh.active_uv_texture
269
270 def faceHasUV(mesh, i, face):
271     return mesh.active_uv_texture.data[i]
272
273 def faceGetUV(mesh, i, faces, count):
274     uvFace=mesh.active_uv_texture.data[i]
275     if count==3:
276         return (uvFace.uv1, uvFace.uv2, uvFace.uv3)
277     elif count==4:
278         return (uvFace.uv1, uvFace.uv2, uvFace.uv3, uvFace.uv4)
279     else:
280         print(count)
281         assert(False)
282
283 def materialToMqo(m):
284     return "\"%s\" shader(3) col(%f %f %f %f)" % (
285             m.name, 
286             m.diffuse_color[0], m.diffuse_color[1], m.diffuse_color[2], 
287             m.alpha)
288
289 def faceMaterialIndex(face):
290     return face.material_index
291
292 def objectGetData(o):
293     return o.data
294
295 def objectAddArmatureModifier(o, armature_object):
296     mod=o.modifiers.new("Modifier", "ARMATURE")
297     mod.object = armature_object
298     mod.use_bone_envelopes=False
299
300 def objectSelect(o):
301     o.selected=True
302
303 def objectGetPose(o):
304     return o.pose
305
306 def poseBoneLimit(n, b):
307     if n.endswith("_t"):
308         return
309     if n.startswith("knee_"):
310         b.ik_dof_y=False
311         b.ik_dof_z=False
312         b.ik_dof_x=True
313         b.ik_limit_x=True
314         b.ik_min_x=0
315         b.ik_max_x=180
316     elif n.startswith("ankle_"):
317         #b.ik_dof_y=False
318         pass
319
320 def enterEditMode():
321     bpy.ops.object.mode_set(mode='EDIT', toggle=False)
322
323 def exitEditMode():
324     bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
325
326 def objectDeselectAll():
327     bpy.ops.object.select_all(action='DESELECT')
328
329 def objectActivate(scene, o):
330     o.selected=True 
331     scene.objects.active=o
332
333 def objectGetActive(scene):
334     return scene.objects.active
335
336 def meshAddVertexGroup(meshObject, name):
337     meshObject.add_vertex_group(name)
338
339 def vertexSetNormal(mvert, normal):
340     mvert.normal=mathutils.Vector(normal)
341
342 def meshUseVertexUv(mesh):
343     pass
344
345 def vertexSetUv(mvert, uv):
346     pass
347
348 def meshAssignVertexGroup(meshObject, name, index, weight):
349     meshObject.add_vertex_to_group(index, 
350                 meshObject.vertex_groups[name], weight, 'ADD')
351
352 def meshCreateVerteicesAndFaces(mesh, vertices, faces):
353     vertexCount=int(len(vertices)/3)
354     faceCount=int(len(faces)/4)
355     mesh.add_geometry(vertexCount, 0, faceCount)
356     mesh.verts.foreach_set("co", vertices)
357     mesh.faces.foreach_set("verts_raw", faces)
358     assert(len(mesh.verts)==vertexCount)
359
360 def meshAddUV(mesh):
361     mesh.add_uv_texture()
362
363 def meshVertsDelete(mesh, remove_vertices):
364     enterEditMode()
365     bpy.ops.mesh.select_all(action='DESELECT')
366     exitEditMode()
367
368     for i in remove_vertices:
369         mesh.verts[i].selected=True
370
371     enterEditMode()
372     bpy.ops.mesh.delete(type='VERT')
373     exitEditMode()
374
375 def createArmature(scene):
376     armature = bpy.data.armatures.new('Armature')
377     armature_object=bpy.data.objects.new('Armature', armature)
378     scene.objects.link(armature_object)
379
380     armature_object.x_ray=True
381     armature.draw_names=True
382     armature.drawtype='OCTAHEDRAL'
383     armature.deform_envelope=False
384     armature.deform_vertexgroups=True
385     armature.x_axis_mirror=True
386
387     return armature, armature_object
388
389 def armatureMakeEditable(scene, armature_object):
390     # select only armature object and set edit mode
391     scene.objects.active=armature_object
392     bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
393     bpy.ops.object.mode_set(mode='EDIT', toggle=False)
394
395 def createIkConstraint(armature_object, p_bone, effector_name, ik):
396     constraint = p_bone.constraints.new('IK')
397     constraint.chain_length=len(ik.children)
398     constraint.target=armature_object
399     constraint.subtarget=effector_name
400     constraint.use_tail=False
401     # not used. place folder when export.
402     constraint.weight=ik.weight
403     constraint.iterations=ik.iterations * 10
404     return constraint
405
406 def createArmatureBone(armature, name):
407     return armature.edit_bones.new(name)
408
409 def boneSetConnected(bone):
410     bone.connected=True
411
412 def createVector(x, y, z):
413     return mathutils.Vector([x, y, z])
414
415 def armatureUpdate(armature):
416     pass
417
418 def boneLayerMask(bone, layers):
419     layer=[]
420     for i in range(32):
421         try:
422             layer.append(True if layers[i]!=0 else False)
423         except IndexError:
424             layer.append(False)
425     bone.layer=layer
426
427 def objectLayerMask(object, layers):
428     layer=[]
429     for i in range(20):
430         try:
431             layer.append(True if layers[i]!=0 else False)
432         except IndexError:
433             layer.append(False)
434     object.layers=layer
435
436 def objectPinShape(o):
437     o.shape_key_lock=True
438
439 def objectAddShapeKey(o, name):
440     return o.add_shape_key(name)
441
442 def objectActivateShapeKey(o, index):
443     o.active_shape_key_index=index
444
445 def shapeKeyAssign(shapeKey, index, pos):
446     shapeKey.data[index].co=pos
447
448 def objectIsVisible(obj):
449     return obj.restrict_view
450
451 def meshVertexGroupNames(meshObject):
452     for g in meshObject.vertex_groups:
453         yield g.name
454
455 def faceNormal(face):
456     return face.normal
457
458 def meshFaceUv(mesh, i, face):
459     return mesh.uv_textures[0].data[i].uv
460
461 def armatureModifierGetObject(m):
462     return m.object
463
464 def objectHasShapeKey(o):
465     return o.data.shape_keys
466
467 def objectShapeKeys(o):
468     return o.data.shape_keys.keys
469
470 def meshVertexGroup(meshObject, name):
471     indices=[]
472     for i, v in enumerate(meshObject.data.verts):
473         for g in v.groups:
474             if meshObject.vertex_groups[g.group].name==name:
475                 indices.append(i)
476     return indices
477
478 def materialGet(scene, material_name):
479     return bpy.data.materials[material_name]
480
481 def modifierIsArmature(m):
482     return m.type=="ARMATURE"
483
484 def boneHeadLocal(b):
485     return b.head_local[0:3]
486
487 def boneTailLocal(b):
488     return b.tail_local[0:3]
489
490 def boneIsConnected(b):
491     return b.connected
492
493 def constraintIsIKSolver(c):
494     return c.type=='IK'
495
496 def ikChainLen(c):
497     return c.chain_length
498
499 def ikTarget(c):
500     return c.subtarget
501
502 def ikItration(c):
503     return c.iterations
504
505 def ikRotationWeight(c):
506     return c.weight
507
508 def shapeKeyGet(b, index):
509     return b.data[index].co
510
511 def shapeKeys(b):
512     for k in b.data:
513         yield k.co
514
515 def VtoV(v):
516     return mathutils.Vector([v.x, v.y, v.z])
517