OSDN Git Service

add pymeshio.
[meshio/meshio.git] / swig / blender / bl24.py
1 # coding: utf-8
2 import sys
3 import os
4
5 try:
6     import Blender
7     from Blender import Mathutils
8     import bpy
9 except:
10     pass
11
12 # ファイルシステムの文字コード
13 # 改造版との共用のため
14 FS_ENCODING=sys.getfilesystemencoding()
15 if os.path.exists(os.path.dirname(sys.argv[0])+"/utf8"):
16     INTERNAL_ENCODING='utf-8'
17 else:
18     INTERNAL_ENCODING=FS_ENCODING
19
20 def to_internal_encoding(fn):
21     '''
22     decorator for fix string encoding
23     '''
24     def newfn(*args):
25         return fn(*[
26             v.encode(INTERNAL_ENCODING) if isinstance(v, unicode) else v 
27             for v in args])
28     return newfn
29
30 def register():
31     pass
32
33 def unregister():
34     pass
35
36 SCENE=None
37 def initialize(name, scene):
38     global SCENE
39     SCENE=scene
40     progress_start(name)
41     # set object mode
42     mode_edit = Blender.Window.EditMode() 
43     if mode_edit: 
44         Blender.Window.EditMode(0)
45
46 def finalize():
47     scene.update(SCENE)
48     progress_finish()
49     # restore edit mode
50     #if mode_edit: 
51     #    Blender.Window.EditMode(1)
52
53 @to_internal_encoding
54 def message(msg):
55     res=Blender.Draw.PupMenu(msg + "%t|OK")
56     print(res)
57
58 def enterEditMode():
59     Blender.Window.EditMode(1)
60
61 def enterObjectMode():
62     Blender.Window.EditMode(0)
63
64 def enterPoseMode():
65     Blender.Window.PoseMode(1)
66
67 def createVector(x, y, z):
68     return Mathutils.Vector(x, y, z)
69
70
71 class Writer(object):
72     '''
73     io wrapper
74     '''
75     __slots__=[
76             'io', 'encoding',
77             ]
78     def __init__(self, path, encoding):
79         '''
80         path: file path to open
81         encoding: text encoding to write
82
83         '''
84         self.io=open(path, "wb")
85         self.encoding=encoding
86
87     def write(self, s):
88         self.io.write(s)
89
90     def flush(self):
91         self.io.flush()
92
93     def close(self):
94         self.io.close()
95
96
97 class ProgressBar(object):
98     '''
99     progress bar wrapper
100     '''
101     __slots__=['base', 'start', 'progress',]
102     def __init__(self, base):
103         print("#### %s ####" % base)
104         self.base=base
105         self.start=Blender.sys.time() 
106         self.set('<start>', 0)
107         Blender.Window.WaitCursor(1) 
108
109     def advance(self, message, progress):
110         self.progress+=float(progress)
111         self._print(message)
112
113     def set(self, message, progress):
114         self.progress=float(progress)
115         self._print(message)
116
117     @to_internal_encoding
118     def _print(self, message):
119         print(message.decode(INTERNAL_ENCODING))
120         message="%s: %s" % (self.base, message)
121         Blender.Window.DrawProgressBar(self.progress, message)
122
123     def finish(self):
124         self.progress=1.0
125         message='finished in %.2f sec' % (Blender.sys.time()-self.start)
126         self.set(message, 1.0)
127         Blender.Window.WaitCursor(0) 
128         Blender.Redraw()
129
130 def progress_start(base):
131     global progressBar
132     progressBar=ProgressBar(base)
133
134 def progress_finish():
135     global progressBar
136     progressBar.finish()
137
138 def progress_print(message, progress=0.05):
139     global progressBar
140     progressBar.advance(message, progress)
141
142 def progress_set(message, progress):
143     global progressBar
144     progressBar.set(message, progress)
145
146
147 class scene:
148     @staticmethod
149     def update(scene):
150         scene.update(0)
151
152
153 class object:
154     @staticmethod
155     @to_internal_encoding
156     def createEmpty(name):
157         global SCENE
158         empty=SCENE.objects.new("Empty")
159         empty.setName(name)
160         return empty
161
162     @staticmethod
163     def each():
164         for o in SCENE.objects:
165             yield o
166
167     @staticmethod
168     def makeParent(parent, child):
169         parent.makeParent([child])
170
171     @staticmethod
172     def duplicate(o):
173         new_mesh, new_object=mesh.create(o.name.decode(INTERNAL_ENCODING))
174         # not apply modifiers
175         new_mesh.getFromObject(o.name, 1)
176         # apply matrix
177         #o.setMatrix(o.matrixWorld)
178         return new_mesh, new_object
179
180     @staticmethod
181     def delete(o):
182         global SCENE
183         SCENE.objects.unlink(o)
184
185     @staticmethod
186     def getData(o):
187         return o.getData(mesh=True)
188
189     @staticmethod
190     def select(o):
191         o.select(True)
192
193     @staticmethod
194     def activate(o):
195         global SCENE
196         o.select(True )
197         SCENE.objects.active=o
198
199     @staticmethod
200     def getActive():
201         global SCENE
202         return SCENE.objects.active
203
204     @staticmethod
205     def deselectAll():
206         for o in bpy.data.scenes.active.objects:
207             o.select(False)
208
209     @staticmethod
210     def setLayerMask(o, layers):
211         mask=0
212         for i, enable in enumerate(layers):
213             if enable!=0:
214                 mask+=(1<<i)
215         o.Layers=mask
216
217     @staticmethod
218     def isVisible(o):
219         return o.restrictDisplay
220
221     @staticmethod
222     def getShapeKeys(o):
223         return o.getData(mesh=True).key.blocks
224
225     @staticmethod
226     @to_internal_encoding
227     def addShapeKey(o, name):
228         mesh=o.getData(mesh=True)
229         mesh.insertKey()
230         block=mesh.key.blocks[-1]
231         block.name=name
232         return block
233
234     @staticmethod
235     def hasShapeKey(o):
236         return o.getData(mesh=True).key
237
238     @staticmethod
239     def pinShape(o, enable):
240         o.pinShape=enable
241
242     @staticmethod
243     def setActivateShapeKey(o, index):
244         o.activeShape=index
245
246     @staticmethod
247     def getPose(o):
248         return o.getPose()
249
250     @staticmethod
251     @to_internal_encoding
252     def addVertexGroup(o, name):
253         o.getData(mesh=True).addVertGroup(name)
254
255     @staticmethod
256     @to_internal_encoding
257     def assignVertexGroup(o, name, index, weight):
258         o.getData(mesh=True).assignVertsToGroup(name, 
259                 [index], weight, Blender.Mesh.AssignModes.ADD)
260
261     @staticmethod
262     def getVertexGroupNames(o):
263         return o.getData(mesh=True).getVertGroupNames()
264
265     @staticmethod
266     @to_internal_encoding
267     def getVertexGroup(o, name):
268         indices=[]
269         for index in o.getData(mesh=True).getVertsFromGroup(name):
270             indices.append(index)
271         return indices
272
273     @staticmethod
274     def createBoneGroup(o, name, color_set='DEFAULT'):
275         # create group
276         object.activate(o)
277         enterPoseMode()
278         bpy.ops.pose.group_add()
279         # set name
280         pose=object.getPose(o)
281         g=pose.active_bone_group
282         g.name=name
283         g.color_set=color_set
284
285     @staticmethod
286     def boneGroups(o):
287         return object.getPose(o).bone_groups
288
289
290 class modifier:
291     @staticmethod
292     def addMirror(mesh_object):
293         return mesh_object.modifiers.append(Blender.Modifier.Types.MIRROR)
294
295     @staticmethod
296     def addArmature(mesh_object, armature_object):
297         mod=mesh_object.modifiers.append(Blender.Modifier.Types.ARMATURE)
298         mod[Blender.Modifier.Settings.OBJECT] = armature_object
299         mod[Blender.Modifier.Settings.ENVELOPES] = False
300
301     @staticmethod
302     def hasType(mesh_object, type_name):
303         for mod in mesh_object.modifiers:
304                 if mod.name.upper()==type_name.upper():
305                     return True
306
307     @staticmethod
308     def isType(m, type_name):
309         return m.name.upper()==type_name.upper()
310
311     @staticmethod
312     def getArmatureObject(m):
313         return m[Blender.Modifier.Settings.OBJECT]
314
315
316 class shapekey:
317     @staticmethod
318     def assign(b, index, pos):
319         b.data[index]=pos
320
321     @staticmethod
322     def getByIndex(b, index):
323         return b.data[index]
324
325     @staticmethod
326     def get(b):
327         return b.data
328
329
330 class texture:
331     @staticmethod
332     @to_internal_encoding
333     def create(path):
334         try:
335             image = Blender.Image.Load(path)
336         except IOError:
337             image = None
338         texture = Blender.Texture.New(path)
339         texture.type = Blender.Texture.Types.IMAGE
340         texture.image = image
341         texture.imageFlags|=Blender.Texture.ImageFlags.USEALPHA
342         return texture, image
343
344     @staticmethod
345     def getPath(t):
346         image=t.getImage()
347         if image:
348             return image.getFilename()
349
350
351 class material:
352     @staticmethod
353     @to_internal_encoding
354     def create(name):
355         m = Blender.Material.New(name)
356         return m
357
358     @staticmethod
359     def get(material_name):
360         return Blender.Material.Get(material_name)
361
362     @staticmethod
363     def addTexture(m, texture, enable=True):
364         for i in xrange(10):
365             if m.textures[i]:
366                 continue
367             if enable:
368                 m.mode = m.mode | Blender.Material.Modes.TEXFACE
369                 m.setTexture(i, texture, Blender.Texture.TexCo.UV)
370             else:
371                 m.setTexture(i, texture)
372                 material.setUseTexture(m, i, False)
373             return i
374
375     @staticmethod
376     def getTexture(m, index):
377         return m.textures[index].tex
378
379     @staticmethod
380     def hasTexture(m):
381         return len(m.getTextures())>0
382
383     @staticmethod
384     def setUseTexture(m, index, enable):
385         enabledTextures=set(m.enabledTextures)
386         if enable:
387             enabledTextures.add(index)
388         else:
389             enabledTextures.remove(index)
390         m.enabledTextures=list(enabledTextures)
391
392     @staticmethod
393     def eachTexturePath(m, dirname):
394         for texture in m.getTextures():
395             if texture and texture.tex and texture.tex.getImage():
396                 image=texture.tex.getImage()
397                 if not image:
398                     continue
399                 yield image.getFilename()
400
401     @staticmethod
402     def eachEnalbeTexturePath(m, dirname):
403         for i, texture in enumerate(m.getTextures()):
404             if (i in m.enabledTextures) and texture and texture.tex and texture.tex.getImage():
405                 image=texture.tex.getImage()
406                 if not image:
407                     continue
408                 yield image.getFilename()
409
410
411 class mesh:
412     @staticmethod
413     @to_internal_encoding
414     def create(name):
415         global SCENE
416         m=Blender.Mesh.New()
417         o=SCENE.objects.new(m, name)
418         return m, o
419
420     @staticmethod
421     def addGeometry(m, vertices, faces):
422         m.verts.extend(vertices)
423         new_faces=m.faces.extend(faces,
424                 #ignoreDups=True, 
425                 indexList=True)
426         m.update()
427
428     @staticmethod
429     def hasUV(m):
430         return m.faceUV
431
432     @staticmethod
433     def useVertexUV(m):
434         m.vertexUV = 1
435
436     @staticmethod
437     def addUV(m):
438         m.addUVLayer('NewUV')
439
440     @staticmethod
441     def hasFaceUV(m, i, face):
442         return len(face.uv)>0
443
444     @staticmethod
445     def getFaceUV(m, i, face, count=3):
446         return face.uv
447
448     @staticmethod
449     def setFaceUV(m, i, face, uv_array, image):
450         face.uv=[Mathutils.Vector(uv[0], uv[1]) for uv in  uv_array]
451         if image:
452             face.image=image
453
454     @staticmethod
455     def vertsDelete(m, remove_vertices):
456         m.verts.delete(remove_vertices)
457
458     @staticmethod
459     def setSmooth(m, smoothing):
460         m.mode |= Blender.Mesh.Modes.AUTOSMOOTH
461         m.degr=int(smoothing)
462         #m.smooth()
463
464     @staticmethod
465     def recalcNormals(mesh_object):
466         m=mesh_object.getData(mesh=True)
467         m.calcNormals() 
468
469     @staticmethod
470     def flipNormals(m):
471         m.flipNormals()
472
473     @staticmethod
474     def addMaterial(m, material):
475         m.materials+=[material]
476
477     @staticmethod
478     def getMaterial(m, index):
479         return m.materials[index]
480
481
482 class vertex:
483     @staticmethod
484     def getNormal(v):
485         return v.no
486
487     @staticmethod
488     def setNormal(v, normal):
489         v.no=Mathutils.Vector(*normal)
490
491     @staticmethod
492     def setUv(v, uv):
493         v.uvco=uv
494
495
496 class face:
497     @staticmethod
498     def getVertexCount(face):
499         return len(face.v)
500
501     @staticmethod
502     def getVertices(face):
503         return [v.index for v in face.v]
504
505     @staticmethod
506     def getIndices(face):
507         return [face.verts[0].index, face.verts[1].index, face.verts[2].index]
508
509     @staticmethod
510     def setMaterial(face, material_index):
511         face.mat=material_index
512
513     @staticmethod
514     def getMaterialIndex(face):
515         return face.mat
516
517     @staticmethod
518     def setNormal(face, normal):
519         face.no=normal
520
521     @staticmethod
522     def getNormal(face):
523         return face.no
524
525     @staticmethod
526     def setSmooth(face, isSmooth):
527         face.smooth=1 if isSmooth else 0
528      
529
530 class armature:
531     @staticmethod
532     def create():
533         global SCENE
534         armature = Blender.Armature.New()
535         armature_object = SCENE.objects.new(armature)
536
537         # set XRAY
538         armature_object.drawMode = (
539                 armature_object.drawMode | Blender.Object.DrawModes.XRAY)
540         # armature settings
541         armature.drawType = Blender.Armature.OCTAHEDRON
542         armature.drawNames=True
543         armature.envelopes = False
544         armature.vertexGroups = True
545         armature.mirrorEdit = True
546
547         return armature, armature_object
548
549     @staticmethod
550     def makeEditable(armature_object):
551         # create armature
552         armature_object.getData().makeEditable()
553
554     @staticmethod
555     def createIkConstraint(armature_object, p_bone, effector_name, ik):
556         cSetting = Blender.Constraint.Settings
557         # IK solver
558         constraint = p_bone.constraints.append(Blender.Constraint.Type.IKSOLVER)
559         constraint[cSetting.CHAINLEN]=len(ik.children)
560         constraint[cSetting.TARGET]=armature_object
561         constraint[cSetting.USETIP]=False
562         constraint[cSetting.BONE]=effector_name
563         # not used. place folder when export.
564         constraint[cSetting.ROTWEIGHT]=ik.weight
565         constraint[cSetting.ITERATIONS]=ik.iterations * 10
566         return constraint
567
568     @staticmethod
569     @to_internal_encoding
570     def createBone(armature_object, name):
571         bone=Blender.Armature.Editbone()
572         bone.name=name
573         armature_object.bones[name]=bone
574         return bone
575
576     @staticmethod
577     def update(armature):
578         armature.update()
579
580
581 class bone:
582     @staticmethod
583     def setConnected(bone):
584         bone.options+=[Blender.Armature.CONNECTED]
585
586     @staticmethod
587     def isConnected(b):
588         return Blender.Armature.CONNECTED in b.options
589
590     @staticmethod
591     def setLayerMask(bone, layers):
592         mask=0
593         for i, enable in enumerate(layers):
594             if enable!=0:
595                 mask+=(1<<i)
596         bone.layerMask=mask
597
598     @staticmethod
599     def getHeadLocal(b):
600         return b.head['ARMATURESPACE'][0:3]
601
602     @staticmethod
603     def getTailLocal(b):
604         return b.tail['ARMATURESPACE'][0:3]
605
606
607 class constraint:
608     @staticmethod
609     def ikChainLen(c):
610         return c[Blender.Constraint.Settings.CHAINLEN]
611
612     @staticmethod
613     def ikTarget(c):
614         return c[Blender.Constraint.Settings.BONE]
615
616     @staticmethod
617     def ikItration(c):
618         return c[Blender.Constraint.Settings.ITERATIONS]
619
620     @staticmethod
621     def ikRotationWeight(c):
622         return c[Blender.Constraint.Settings.ROTWEIGHT]
623
624     @staticmethod
625     def isIKSolver(c):
626         return c.type==Blender.Constraint.Type.IKSOLVER
627