OSDN Git Service

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