OSDN Git Service

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