OSDN Git Service

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