OSDN Git Service

9c5a573917f6556df50f95e388eff94f2d4ff00a
[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_object, o, materials, imageMap, scale):
145     mesh=mesh_object.data
146     # count triangle and quadrangle
147     faceCount=0
148     for f in o.faces:
149         if f.index_count==3 or f.index_count==4:
150             faceCount+=1
151     mesh.add_geometry(len(o.vertices), 0, faceCount)
152
153     # add vertex
154     unpackedVertices=[]
155     for v in o.vertices:
156         # convert right-handed y-up to right-handed z-up
157         unpackedVertices.extend(
158                 (scale*v.x, scale*-v.z, scale*v.y))
159     mesh.verts.foreach_set("co", unpackedVertices)
160
161     # add face
162     unpackedFaces = []
163     usedMaterial=set()
164
165     def getFace(f):
166         face = []
167         for i in range(f.index_count):
168             face.append(f.getIndex(i))
169         return face
170
171     for f in o.faces:
172         face=getFace(f)
173         if len(face) != 3 and len(face) != 4:
174             print("{0} vertices in face.".format(len(face)))
175             continue
176
177         if len(face) == 4:
178             if face[3] == 0:
179                 # rotate indices if the 4th is 0
180                 face = [face[3], face[0], face[1], face[2]]
181         elif len(face) == 3:
182             if face[2] == 0:
183                 # rotate indices if the 3rd is 0
184                 face = [face[2], face[0], face[1], 0]
185             else:
186                 face.append(0)
187
188         unpackedFaces.extend(face)
189         usedMaterial.add(f.material_index)
190     try:
191         mesh.faces.foreach_set("verts_raw", unpackedFaces)
192     except:
193         #print([getFace(f) for f in o.faces])
194         print("fail to mesh.faces.foreach_set")
195         return
196
197     # add material
198     meshMaterialMap={}
199     materialIndex=0
200     for i in usedMaterial:
201         mesh.add_material(materials[i])
202         meshMaterialMap[i]=materialIndex
203         materialIndex+=1
204
205     # each face
206     mesh.add_uv_texture()
207     for mqo_face, blender_face, uv_face in zip(
208             o.faces, mesh.faces, mesh.uv_textures[0].data):
209         if mqo_face.index_count<3:
210             continue
211         blender_face.material_index=meshMaterialMap[mqo_face.material_index]
212         if mqo_face.index_count>=3:
213             uv_face.uv1=[mqo_face.getUV(0).x, 1.0-mqo_face.getUV(0).y]
214             uv_face.uv2=[mqo_face.getUV(1).x, 1.0-mqo_face.getUV(1).y]
215             uv_face.uv3=[mqo_face.getUV(2).x, 1.0-mqo_face.getUV(2).y]
216             if mqo_face.index_count==4:
217                 uv_face.uv4=[
218                         mqo_face.getUV(3).x, 1.0-mqo_face.getUV(3).y]
219         if materials[mqo_face.material_index] in imageMap:
220             uv_face.image=imageMap[mqo_face.material_index]
221             uv_face.tex=True
222
223     mesh.update()
224
225 def getTexture(m, dirname):
226     tex=""
227     aplane=""
228     # texture
229     for slot in m.texture_slots:
230         if slot and slot.texture:
231             texture=slot.texture
232             if  texture.type=="IMAGE":
233                 image=texture.image
234                 if not image:
235                     continue
236                 imagePath=image.filename
237                 if len(dirname)>0 and imagePath.startswith(dirname):
238                     # \e$BAjBP%Q%9$KJQ49$9$k\e(B
239                     imagePath=imagePath[len(dirname)+1:len(imagePath)]
240                 #imagePath=Blender.sys.expandpath(
241                 #        imagePath).replace("\\", '/')
242                 if slot.map_colordiff:
243                     tex=" tex(\"%s\")" % imagePath
244                 elif slot.map_alpha:
245                     aplane=" aplane(\"%s\")" % imagePath
246     return tex, aplane
247
248 def objectDuplicate(scene, obj):
249     bpy.ops.object.select_all(action='DESELECT')
250     obj.selected=True
251     scene.objects.active=obj
252     bpy.ops.object.duplicate()
253     dumy=scene.objects.active
254     bpy.ops.object.rotation_apply()
255     bpy.ops.object.scale_apply()
256     bpy.ops.object.location_apply()
257     return dumy.data, dumy
258
259 def objectDelete(scene, obj):
260     scene.objects.unlink(obj)
261
262 def faceVertexCount(face):
263     return len(face.verts)
264
265 def faceVertices(face):
266     return face.verts[:]
267
268 def meshHasUV(mesh):
269     return mesh.active_uv_texture
270
271 def faceHasUV(mesh, i, face):
272     return mesh.active_uv_texture.data[i]
273
274 def faceGetUV(mesh, i, faces, count):
275     uvFace=mesh.active_uv_texture.data[i]
276     if count==3:
277         return (uvFace.uv1, uvFace.uv2, uvFace.uv3)
278     elif count==4:
279         return (uvFace.uv1, uvFace.uv2, uvFace.uv3, uvFace.uv4)
280     else:
281         print(count)
282         assert(False)
283
284 def materialToMqo(m):
285     return "\"%s\" shader(3) col(%f %f %f %f)" % (
286             m.name, 
287             m.diffuse_color[0], m.diffuse_color[1], m.diffuse_color[2], 
288             m.alpha)
289
290 def faceMaterialIndex(face):
291     return face.material_index
292
293 def objectGetData(o):
294     return o.data
295
296 def objectAddArmatureModifier(o, armature_object):
297     mod=o.modifiers.new("Modifier", "ARMATURE")
298     mod.object = armature_object
299     mod.use_bone_envelopes=False
300
301 def objectSelect(o):
302     o.selected=True
303
304 def objectGetPose(o):
305     return o.pose
306
307 def poseBoneLimit(n, b):
308     if n.endswith("_t"):
309         return
310     if n.startswith("knee_"):
311         b.ik_dof_y=False
312         b.ik_dof_z=False
313         b.ik_dof_x=True
314         b.ik_limit_x=True
315         b.ik_min_x=0
316         b.ik_max_x=180
317     elif n.startswith("ankle_"):
318         #b.ik_dof_y=False
319         pass
320
321 def enterEditMode():
322     bpy.ops.object.mode_set(mode='EDIT', toggle=False)
323
324 def exitEditMode():
325     bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
326
327 def objectDeselectAll():
328     bpy.ops.object.select_all(action='DESELECT')
329
330 def objectActivate(scene, o):
331     o.selected=True 
332     scene.objects.active=o
333
334 def objectGetActive(scene):
335     return scene.objects.active
336
337 def meshAddVertexGroup(meshObject, name):
338     meshObject.add_vertex_group(name)
339
340 def vertexSetNormal(mvert, normal):
341     mvert.normal=mathutils.Vector(normal)
342
343 def meshUseVertexUv(mesh):
344     pass
345
346 def vertexSetUv(mvert, uv):
347     pass
348
349 def meshAssignVertexGroup(meshObject, name, index, weight):
350     meshObject.add_vertex_to_group(index, 
351                 meshObject.vertex_groups[name], weight, 'ADD')
352
353 def meshCreateVerteicesAndFaces(mesh, vertices, faces):
354     vertexCount=int(len(vertices)/3)
355     faceCount=int(len(faces)/4)
356     mesh.add_geometry(vertexCount, 0, faceCount)
357     mesh.verts.foreach_set("co", vertices)
358     mesh.faces.foreach_set("verts_raw", faces)
359     assert(len(mesh.verts)==vertexCount)
360
361 def meshAddUV(mesh):
362     mesh.add_uv_texture()
363
364 def meshVertsDelete(mesh, remove_vertices):
365     enterEditMode()
366     bpy.ops.mesh.select_all(action='DESELECT')
367     exitEditMode()
368
369     for i in remove_vertices:
370         mesh.verts[i].selected=True
371
372     enterEditMode()
373     bpy.ops.mesh.delete(type='VERT')
374     exitEditMode()
375
376 def createArmature(scene):
377     armature = bpy.data.armatures.new('Armature')
378     armature_object=bpy.data.objects.new('Armature', armature)
379     scene.objects.link(armature_object)
380
381     armature_object.x_ray=True
382     armature.draw_names=True
383     armature.drawtype='OCTAHEDRAL'
384     armature.deform_envelope=False
385     armature.deform_vertexgroups=True
386     armature.x_axis_mirror=True
387
388     return armature, armature_object
389
390 def armatureMakeEditable(scene, armature_object):
391     # select only armature object and set edit mode
392     scene.objects.active=armature_object
393     bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
394     bpy.ops.object.mode_set(mode='EDIT', toggle=False)
395
396 def createIkConstraint(armature_object, p_bone, effector_name, ik):
397     constraint = p_bone.constraints.new('IK')
398     constraint.chain_length=len(ik.children)
399     constraint.target=armature_object
400     constraint.subtarget=effector_name
401     constraint.use_tail=False
402     # not used. place folder when export.
403     constraint.weight=ik.weight
404     constraint.iterations=ik.iterations * 10
405     return constraint
406
407 def createArmatureBone(armature, name):
408     return armature.edit_bones.new(name)
409
410 def boneSetConnected(bone):
411     bone.connected=True
412
413 def createVector(x, y, z):
414     return mathutils.Vector([x, y, z])
415
416 def armatureUpdate(armature):
417     pass
418
419 def boneLayerMask(bone, layers):
420     layer=[]
421     for i in range(32):
422         try:
423             layer.append(True if layers[i]!=0 else False)
424         except IndexError:
425             layer.append(False)
426     bone.layer=layer
427
428 def objectLayerMask(object, layers):
429     layer=[]
430     for i in range(20):
431         try:
432             layer.append(True if layers[i]!=0 else False)
433         except IndexError:
434             layer.append(False)
435     object.layers=layer
436
437 def objectPinShape(o):
438     o.shape_key_lock=True
439
440 def objectAddShapeKey(o, name):
441     return o.add_shape_key(name)
442
443 def objectActivateShapeKey(o, index):
444     o.active_shape_key_index=index
445
446 def shapeKeyAssign(shapeKey, index, pos):
447     shapeKey.data[index].co=pos
448
449 def objectIsVisible(obj):
450     return obj.restrict_view
451
452 def meshVertexGroupNames(meshObject):
453     for g in meshObject.vertex_groups:
454         yield g.name
455
456 def faceNormal(face):
457     return face.normal
458
459 def meshFaceUv(mesh, i, face):
460     return mesh.uv_textures[0].data[i].uv
461
462 def armatureModifierGetObject(m):
463     return m.object
464
465 def objectHasShapeKey(o):
466     return o.data.shape_keys
467
468 def objectShapeKeys(o):
469     return o.data.shape_keys.keys
470
471 def meshVertexGroup(meshObject, name):
472     indices=[]
473     for i, v in enumerate(meshObject.data.verts):
474         for g in v.groups:
475             if meshObject.vertex_groups[g.group].name==name:
476                 indices.append(i)
477     return indices
478
479 def materialGet(scene, material_name):
480     return bpy.data.materials[material_name]
481
482 def modifierIsArmature(m):
483     return m.type=="ARMATURE"
484
485 def boneHeadLocal(b):
486     return b.head_local[0:3]
487
488 def boneTailLocal(b):
489     return b.tail_local[0:3]
490
491 def boneIsConnected(b):
492     return b.connected
493
494 def constraintIsIKSolver(c):
495     return c.type=='IK'
496
497 def ikChainLen(c):
498     return c.chain_length
499
500 def ikTarget(c):
501     return c.subtarget
502
503 def ikItration(c):
504     return c.iterations
505
506 def ikRotationWeight(c):
507     return c.weight
508
509 def shapeKeyGet(b, index):
510     return b.data[index].co
511
512 def shapeKeys(b):
513     for k in b.data:
514         yield k.co
515
516 def VtoV(v):
517     return mathutils.Vector([v.x, v.y, v.z])
518