OSDN Git Service

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