OSDN Git Service

fix 2.4.
[meshio/meshio.git] / swig / blender / bl25.py
1 # coding: utf-8
2 import os
3 import sys
4 import time
5 import functools
6
7 try:
8     import bpy
9     import mathutils
10 except:
11     pass
12
13\e$B%U%!%$%k%7%9%F%`$NJ8;z%3!<%I\e(B
14\e$B2~B$HG$H$N6&MQ$N$?$a\e(B
15 FS_ENCODING=sys.getfilesystemencoding()
16 if os.path.exists(os.path.dirname(sys.argv[0])+"/utf8"):
17     INTERNAL_ENCODING='utf-8'
18 else:
19     INTERNAL_ENCODING=FS_ENCODING
20
21 SCENE=None
22 def initialize(name, scene):
23     global SCENE
24     SCENE=scene
25     progress_start(name)
26
27 def finalize():
28     scene.update(SCENE)
29     progress_finish()
30
31 def message(msg):
32     pass
33
34 def enterEditMode():
35     bpy.ops.object.mode_set(mode='EDIT', toggle=False)
36
37 def enterObjectMode():
38     bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
39
40 def enterPoseMode():
41     bpy.ops.object.mode_set(mode='POSE', toggle=False)
42
43 def createVector(x, y, z):
44     return mathutils.Vector([x, y, z])
45
46
47 class Writer(object):
48     '''
49     io wrapper
50     '''
51     def __init__(self, path, encoding):
52         self.io=open(path, "wb")
53         self.encoding=encoding
54
55     def write(self, s):
56         self.io.write(s.encode(self.encoding))
57
58     def flush(self):
59         self.io.flush()
60
61     def close(self):
62         self.io.close()
63
64
65 class ProgressBar(object):
66     '''
67     progress bar wrapper
68     '''
69     def __init__(self, base):
70         print("#### %s ####" % base)
71         self.base=base
72         self.start=time.time() 
73         self.set('<start>', 0)
74
75     def advance(self, message, progress):
76         self.progress+=float(progress)
77         self._print(message)
78
79     def set(self, message, progress):
80         self.progress=float(progress)
81         self._print(message)
82
83     def _print(self, message):
84         print(message)
85         message="%s: %s" % (self.base, message)
86         #Blender.Window.DrawProgressBar(self.progress, message)
87
88     def finish(self):
89         self.progress=1.0
90         message='finished in %.2f sec' % (time.time()-self.start)
91         self.set(message, 1.0)
92
93 def progress_start(base):
94     global progressBar
95     progressBar=ProgressBar(base)
96
97 def progress_finish():
98     global progressBar
99     progressBar.finish()
100
101 def progress_print(message, progress=0.05):
102     global progressBar
103     progressBar.advance(message, progress)
104
105 def progress_set(message, progress):
106     global progressBar
107     progressBar.set(message, progress)
108
109
110 class scene:
111     @staticmethod
112     def update(scene):
113         scene.update()
114
115
116 class object:
117     @staticmethod
118     def createEmpty(name):
119         global SCENE
120         empty=bpy.data.objects.new(name, None)
121         SCENE.objects.link(empty)
122         return empty
123
124     @staticmethod
125     def makeParent(parent, child):
126         child.parent=parent
127
128     @staticmethod
129     def duplicate(o):
130         global SCENE
131         bpy.ops.object.select_all(action='DESELECT')
132         o.selected=True
133         SCENE.objects.active=o
134         bpy.ops.object.duplicate()
135         dumy=SCENE.objects.active
136         #bpy.ops.object.rotation_apply()
137         #bpy.ops.object.scale_apply()
138         #bpy.ops.object.location_apply()
139         return dumy.data, dumy
140
141     @staticmethod
142     def delete(o):
143         global SCENE
144         SCENE.objects.unlink(o)
145
146     @staticmethod
147     def getData(o):
148         return o.data
149
150     @staticmethod
151     def select(o):
152         o.selected=True
153
154     @staticmethod
155     def activate(o):
156         global SCENE
157         o.selected=True 
158         SCENE.objects.active=o
159
160     @staticmethod
161     def getActive():
162         global SCENE 
163         return SCENE.objects.active
164
165     @staticmethod
166     def deselectAll():
167         bpy.ops.object.select_all(action='DESELECT')
168
169     @staticmethod
170     def setLayerMask(object, layers):
171         layer=[]
172         for i in range(20):
173             try:
174                 layer.append(True if layers[i]!=0 else False)
175             except IndexError:
176                 layer.append(False)
177         object.layers=layer
178
179     @staticmethod
180     def isVisible(o):
181         return o.restrict_view
182
183     @staticmethod
184     def getShapeKeys(o):
185         return o.data.shape_keys.keys
186
187     @staticmethod
188     def addShapeKey(o, name):
189         return o.add_shape_key(name)
190
191     @staticmethod
192     def hasShapeKey(o):
193         return o.data.shape_keys
194
195     @staticmethod
196     def pinShape(o, enable):
197         o.shape_key_lock=enable
198
199     @staticmethod
200     def setActivateShapeKey(o, index):
201         o.active_shape_key_index=index
202
203     @staticmethod
204     def getPose(o):
205         return o.pose
206
207     @staticmethod
208     def getVertexGroup(o, name):
209         indices=[]
210         for i, v in enumerate(o.data.verts):
211             for g in v.groups:
212                 if o.vertex_groups[g.group].name==name:
213                     indices.append(i)
214         return indices
215
216     @staticmethod
217     def getVertexGroupNames(o):
218         for g in o.vertex_groups:
219             yield g.name
220
221     @staticmethod
222     def addVertexGroup(o, name):
223         o.add_vertex_group(name)
224
225     @staticmethod
226     def assignVertexGroup(o, name, index, weight):
227         o.add_vertex_to_group(index, 
228                     o.vertex_groups[name], weight, 'ADD')
229
230     @staticmethod
231     def createBoneGroup(o, name, color_set='DEFAULT'):
232         # create group
233         object.activate(o)
234         enterPoseMode()
235         bpy.ops.pose.group_add()
236         # set name
237         pose=object.getPose(o)
238         g=pose.active_bone_group
239         g.name=name
240         g.color_set=color_set
241
242
243 class modifier:
244     @staticmethod
245     def addMirror(mesh_object):
246         return mesh_object.modifiers.new("Modifier", "MIRROR")
247
248     @staticmethod
249     def addArmature(mesh_object, armature_object):
250         mod=mesh_object.modifiers.new("Modifier", "ARMATURE")
251         mod.object = armature_object
252         mod.use_bone_envelopes=False
253
254     @staticmethod
255     def hasType(mesh_object, type_name):
256         for mod in mesh_object.modifiers:
257                 if mod.type==type_name.upper():
258                     return True
259
260     @staticmethod
261     def isType(m, type_name):
262         return m.type==type_name.upper()
263
264     @staticmethod
265     def getArmatureObject(m):
266         return m.object
267
268
269 class shapekey:
270     @staticmethod
271     def assign(shapeKey, index, pos):
272         shapeKey.data[index].co=pos
273
274     @staticmethod
275     def getByIndex(b, index):
276         return b.data[index].co
277
278     @staticmethod
279     def get(b):
280         for k in b.data:
281             yield k.co
282
283
284 class texture:
285     @staticmethod
286     def create(path):
287         texture=bpy.data.textures.new(os.path.basename(path))
288         texture.type='IMAGE'
289         texture=texture.recast_type()
290         image=bpy.data.images.load(path)
291         texture.image=image
292         texture.mipmap=True
293         texture.interpolation=True
294         texture.use_alpha=True
295         return texture, image
296
297
298 class material:
299     @staticmethod
300     def create(name):
301         return bpy.data.materials.new(name)
302
303     @staticmethod
304     def get(material_name):
305         return bpy.data.materials[material_name]
306
307     @staticmethod
308     def addTexture(material, texture, enable=True):
309         # search free slot
310         index=None
311         for i, slot in enumerate(material.texture_slots):
312             if not slot:
313                 index=i
314                 break
315         if index==None:
316             return
317
318         if enable:
319             material.add_texture(texture, "UV", "COLOR")
320             slot=material.texture_slots[index]
321             slot.blend_type='MULTIPLY'
322             slot.map_alpha=True
323         else:
324             material.add_texture(texture)
325             material.use_textures[index]=False
326         return index
327
328     @staticmethod
329     def getTexture(material, index):
330         return material.texture_slots[index].texture
331
332     @staticmethod
333     def hasTexture(material):
334         return material.texture_slots[0]
335
336     @staticmethod
337     def setUseTexture(material, index, enable):
338         material.use_textures[index]=enable
339
340     @staticmethod
341     def eachTexturePath(m):
342         for slot in m.texture_slots:
343             if slot and slot.texture:
344                 texture=slot.texture
345                 if  texture.type=="IMAGE":
346                     image=texture.image
347                     if not image:
348                         continue
349                     yield image.filename
350
351 class mesh:
352     @staticmethod
353     def create(name):
354         global SCENE
355         mesh=bpy.data.meshes.new("Mesh")
356         mesh_object= bpy.data.objects.new(name, mesh)
357         SCENE.objects.link(mesh_object)
358         return mesh, mesh_object
359
360     @staticmethod
361     def addGeometry(mesh, vertices, faces):
362         mesh.from_pydata(vertices, [], faces)
363         """
364         mesh.add_geometry(len(vertices), 0, len(faces))
365         # add vertex
366         unpackedVertices=[]
367         for v in vertices:
368             unpackedVertices.extend(v)
369         mesh.verts.foreach_set("co", unpackedVertices)
370         # add face
371         unpackedFaces = []
372         for face in faces:
373             if len(face) == 4:
374                 if face[3] == 0:
375                     # rotate indices if the 4th is 0
376                     face = [face[3], face[0], face[1], face[2]]
377             elif len(face) == 3:
378                 if face[2] == 0:
379                     # rotate indices if the 3rd is 0
380                     face = [face[2], face[0], face[1], 0]
381                 else:
382                     face.append(0)
383             unpackedFaces.extend(face)
384         mesh.faces.foreach_set("verts_raw", unpackedFaces)
385         """
386         assert(len(vertices)==len(mesh.verts))
387         assert(len(faces)==len(mesh.faces))
388
389     @staticmethod
390     def hasUV(mesh):
391         return mesh.active_uv_texture
392
393     @staticmethod
394     def useVertexUV(mesh):
395         pass
396
397     @staticmethod
398     def addUV(mesh):
399         mesh.add_uv_texture()
400
401     @staticmethod
402     def hasFaceUV(mesh, i, face):
403         return mesh.active_uv_texture and mesh.active_uv_texture.data[i]
404
405     @staticmethod
406     def getFaceUV(mesh, i, faces, count=3):
407         if mesh.active_uv_texture and mesh.active_uv_texture.data[i]:
408             uvFace=mesh.active_uv_texture.data[i]
409             if count==3:
410                 return (uvFace.uv1, uvFace.uv2, uvFace.uv3)
411             elif count==4:
412                 return (uvFace.uv1, uvFace.uv2, uvFace.uv3, uvFace.uv4)
413             else:
414                 print(count)
415                 assert(False)
416         else:
417             return ((0, 0), (0, 0), (0, 0), (0, 0))
418
419     @staticmethod
420     def setFaceUV(mesh, i, face, uv_array, image):
421         uv_face=mesh.uv_textures[0].data[i]
422         uv_face.uv=uv_array
423         if image:
424             uv_face.image=image
425             uv_face.tex=True
426
427     @staticmethod
428     def vertsDelete(mesh, remove_vertices):
429         enterEditMode()
430         bpy.ops.mesh.select_all(action='DESELECT')
431         enterObjectMode()
432
433         for i in remove_vertices:
434             mesh.verts[i].selected=True
435
436         enterEditMode()
437         bpy.ops.mesh.delete(type='VERT')
438         enterObjectMode()
439
440     @staticmethod
441     def setSmooth(mesh, smoothing):
442         mesh.autosmooth_angle=int(smoothing)
443         mesh.autosmooth=True
444
445     @staticmethod
446     def recalcNormals(mesh_object):
447         bpy.ops.object.select_all(action='DESELECT')
448         object.activate(mesh_object)
449         enterEditMode()
450         bpy.ops.mesh.normals_make_consistent()
451         enterObjectMode()
452
453     @staticmethod
454     def flipNormals(mesh):
455         mesh.flipNormals()
456
457     @staticmethod
458     def addMaterial(mesh, material):
459         mesh.add_material(material)
460
461
462 class vertex:
463     @staticmethod
464     def setNormal(mvert, normal):
465         mvert.normal=mathutils.Vector(normal)
466
467     @staticmethod
468     def setUv(mvert, uv):
469         pass
470
471
472 class face:
473     @staticmethod
474     def getVertexCount(face):
475         return len(face.verts)
476
477     @staticmethod
478     def getVertices(face):
479         return face.verts[:]
480
481     @staticmethod
482     def getIndices(face, count=3):
483         if count==3:
484             return [face.verts[0], face.verts[1], face.verts[2]]
485         elif count==4:
486             return [face.verts[0], face.verts[1], face.verts[2], face.verts[3]]
487         else:
488             assert(False)
489
490     @staticmethod
491     def setMaterial(face, material_index):
492         face.material_index=material_index
493
494     @staticmethod
495     def getMaterialIndex(face):
496         return face.material_index
497
498     @staticmethod
499     def setNormal(face, normal):
500         face.normal=normal
501
502     @staticmethod
503     def getNormal(face):
504         return face.normal
505
506     @staticmethod
507     def setSmooth(face, isSmooth):
508         face.smooth=True if isSmooth else False
509
510
511 class armature:
512     @staticmethod
513     def create():
514         global SCENE
515         armature = bpy.data.armatures.new('Armature')
516         armature_object=bpy.data.objects.new('Armature', armature)
517         SCENE.objects.link(armature_object)
518
519         armature_object.x_ray=True
520         armature.draw_names=True
521         #armature.drawtype='OCTAHEDRAL'
522         armature.drawtype='STICK'
523         armature.deform_envelope=False
524         armature.deform_vertexgroups=True
525         armature.x_axis_mirror=True
526
527         return armature, armature_object
528
529     @staticmethod
530     def makeEditable(armature_object):
531         global SCENE
532         # select only armature object and set edit mode
533         SCENE.objects.active=armature_object
534         bpy.ops.object.mode_set(mode='OBJECT', toggle=False)
535         bpy.ops.object.mode_set(mode='EDIT', toggle=False)
536
537     @staticmethod
538     def createIkConstraint(armature_object, p_bone, effector_name, ik):
539         constraint = p_bone.constraints.new('IK')
540         constraint.chain_length=len(ik.children)
541         constraint.target=armature_object
542         constraint.subtarget=effector_name
543         constraint.use_tail=False
544         # not used. place folder when export.
545         constraint.weight=ik.weight
546         constraint.iterations=ik.iterations * 10
547         return constraint
548
549     @staticmethod
550     def createBone(armature, name):
551         return armature.edit_bones.new(name)
552
553     @staticmethod
554     def update(armature):
555         pass
556
557
558 class bone:
559     @staticmethod
560     def setConnected(bone):
561         bone.connected=True
562
563     @staticmethod
564     def isConnected(b):
565         return b.connected
566
567     @staticmethod
568     def setLayerMask(bone, layers):
569         layer=[]
570         for i in range(32):
571             try:
572                 layer.append(True if layers[i]!=0 else False)
573             except IndexError:
574                 layer.append(False)
575         bone.layer=layer
576
577     @staticmethod
578     def getHeadLocal(b):
579         return b.head_local[0:3]
580
581     @staticmethod
582     def getTailLocal(b):
583         return b.tail_local[0:3]
584
585
586 class constraint:
587     @staticmethod
588     def ikChainLen(c):
589         return c.chain_length
590
591     @staticmethod
592     def ikTarget(c):
593         return c.subtarget
594
595     @staticmethod
596     def ikItration(c):
597         return c.iterations
598
599     @staticmethod
600     def ikRotationWeight(c):
601         return c.weight
602
603     @staticmethod
604     def isIKSolver(c):
605         return c.type=='IK'
606
607