OSDN Git Service

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